From 129cc6afd4ac49b458659ae8bb0d5201942c2aab Mon Sep 17 00:00:00 2001 From: Mihai Moldovan <ïonic@ionic.de> Date: Fri, 27 May 2016 15:52:50 +0000 Subject: nx-X11/programs/Xserver/hw/nxagent/Handlers.h: fix stack smashing related to different data type sizes between Xserver and Xlib. While on the X server side we were expecting a 32bit value, the Xlib side in nxcompext wrote a 64bit integer to the 32bit location, hence overwriting "random" data on the stack (most notably the return adress.) We can work around this by using the Xlib-based Window data type on the server-side as well, but this problem is likely a more general one. Calling functions from libcompext in nxagent sounds like a bad idea. Other code locations might well be affected by issues alike to that as well. In order to silence compiler warnings, use a "macro hack" for overriding the "Window" type in NXlib.h. --- nx-X11/programs/Xserver/hw/nxagent/Handlers.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'nx-X11/programs/Xserver/hw') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c index cadb8e58a..1beff090b 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c @@ -32,7 +32,10 @@ #include "Screen.h" #include "Millis.h" +#define Window XlibWindow #include +#undef Window + #include /* @@ -956,7 +959,24 @@ void nxagentShadowWakeupHandler(void * data, int count, void * mask) void nxagentHandleCollectInputFocusEvent(int resource) { - Window window; + /* + * While we don't even need window or revert_to later on, a discrepancy in + * data type sizes between the X server (Window being a 32bit ID) and + * the Xlib (Window being a 64bit ID) will lead to stack corruption here. + * Calling functions from nxcompext from nxagent sounds like a very bad idea + * to begin with, but let's assume that's necessary for now and work around + * the corruption issue. + * + * Even though the NXlib header shows that the function expects a Window-sized + * parameter, it's not the Window type as defined and used within the X.Org + * Server, but an Xlib type. Hence, we'll be using the "XlibWindow" type here + * and to avoid compiler warnings, "rewrite" the NXlib.h header file via + * overriding the original "Window" type with the XlibWindow type, including + * the header file and undefining the macro again, essentially unshadowing + * the original type. + */ + XlibWindow window; + int revert_to; if (NXGetCollectedInputFocus(nxagentDisplay, resource, &window, &revert_to) == 0) -- cgit v1.2.3 From 04d2fe3aef464560de16d5b15ed91f8d63c6fb09 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Mon, 13 Jun 2016 01:56:07 +0200 Subject: nxagentReversePointerMap: Don't assume Xevent.xbutton.button is always greater than zero. We have seen Xevent.xbutton.button being set to AnyButton (equaling 0). Fixes ArcticaProject/nx-libs#92 Fixes X2GoBTS#791 --- nx-X11/programs/Xserver/hw/nxagent/Events.c | 4 ++-- nx-X11/programs/Xserver/hw/nxagent/Pointer.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'nx-X11/programs/Xserver/hw') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c index ffb593750..0a6540fa3 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Events.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c @@ -1252,7 +1252,7 @@ FIXME: Don't enqueue the KeyRelease event if the key was X.xbutton.subwindow == None)) { x.u.u.type = ButtonPress; - x.u.u.detail = inputInfo.pointer -> button -> map[nxagentReversePointerMap[X.xbutton.button - 1]]; + x.u.u.detail = inputInfo.pointer -> button -> map[nxagentReversePointerMap[X.xbutton.button]]; x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis(); if (nxagentOption(Rootless)) @@ -1325,7 +1325,7 @@ FIXME: Don't enqueue the KeyRelease event if the key was if (minimize != True) { x.u.u.type = ButtonRelease; - x.u.u.detail = inputInfo.pointer -> button -> map[nxagentReversePointerMap[X.xbutton.button - 1]]; + x.u.u.detail = inputInfo.pointer -> button -> map[nxagentReversePointerMap[X.xbutton.button]]; x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis(); if (nxagentOption(Rootless)) diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pointer.c b/nx-X11/programs/Xserver/hw/nxagent/Pointer.c index ce2b37a90..8a8ed85b1 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Pointer.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Pointer.c @@ -186,6 +186,6 @@ void nxagentInitPointerMap(void) for (i = 1; i <= numButtons; i++) { - nxagentReversePointerMap[pointerMap[i - 1] - 1] = i; + nxagentReversePointerMap[pointerMap[i - 1]] = i; } } -- cgit v1.2.3 From 4d6d3c56706e0c5a0725c13356c28d3655f72cac Mon Sep 17 00:00:00 2001 From: Mihai Moldovan <ïonic@ionic.de> Date: Fri, 17 Jun 2016 01:45:40 +0000 Subject: {nx-X11/programs/Xserver/hw/nxagent/{{Args,Handlers,Image,Options}.c,Options.h},nxcomp/{Loop,Misc}.cpp}: add configurable sleep delay if session is suspended. --- nx-X11/programs/Xserver/hw/nxagent/Args.c | 38 ++++++++++++++++++++++ nx-X11/programs/Xserver/hw/nxagent/Handlers.c | 46 +++++++++++++++++++-------- nx-X11/programs/Xserver/hw/nxagent/Image.c | 14 ++------ nx-X11/programs/Xserver/hw/nxagent/Options.c | 2 ++ nx-X11/programs/Xserver/hw/nxagent/Options.h | 7 ++++ nxcomp/Loop.cpp | 3 +- nxcomp/Misc.cpp | 3 +- 7 files changed, 87 insertions(+), 26 deletions(-) (limited to 'nx-X11/programs/Xserver/hw') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.c b/nx-X11/programs/Xserver/hw/nxagent/Args.c index 59d3deb63..2590dd6c3 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Args.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Args.c @@ -1339,6 +1339,44 @@ static void nxagentParseOptions(char *name, char *value) nxagentChangeOption(Clipboard, ClipboardBoth); } } + else if (!strcmp(name, "sleep")) + { + long sleep_parse = 0; + + errno = 0; + sleep_parse = strtol(value, NULL, 10); + + if ((errno) && (0 == sleep_parse)) + { + fprintf(stderr, "nxagentParseOptions: Unable to convert value [%s] of option [%s]. " + "Ignoring option.\n", + validateString(value), validateString(name)); + + return; + } + + if ((long) UINT_MAX < sleep_parse) + { + sleep_parse = UINT_MAX; + + fprintf(stderr, "nxagentParseOptions: Warning: value [%s] of option [%s] " + "out of range, clamped to [%u].\n", + validateString(value), validateString(name), sleep_parse); + } + + if (0 > sleep_parse) + { + sleep_parse = 0; + + fprintf(stderr, "nxagentParseOptions: Warning: value [%s] of option [%s] " + "out of range, clamped to [%u].\n", + validateString(value), validateString(name), sleep_parse); + } + + nxagentChangeOption(SleepTime, sleep_parse); + + return; + } else { #ifdef DEBUG diff --git a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c index 1beff090b..ba4034255 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c @@ -62,14 +62,6 @@ #define FLUSH_AFTER_MULTIPLE_READS -/* - * Introduce a small delay after each - * loop if the session is down. The - * value is in milliseconds. - */ - -#define LOOP_DELAY_IF_DOWN 50 - /* * The soft limit should roughly match * the size of the Xlib I/O buffer. @@ -246,12 +238,21 @@ void nxagentBlockHandler(void * data, struct timeval **timeout, void * mask) * not connected to a valid display. */ - if (NXDisplayError(nxagentDisplay) == 1 && nxagentShadowCounter == 0) + if (NXDisplayError(nxagentDisplay) == 1 && nxagentShadowCounter == 0 && nxagentOption(SleepTime) > 0) { - usleep(LOOP_DELAY_IF_DOWN * 1000); +#ifdef TEST + fprintf(stderr, "nxagentBlockHandler: sleeping for %d milliseconds for slowdown.\n", + nxagentOption(SleepTime)); +#endif + usleep(nxagentOption(SleepTime) * 1000); now = GetTimeInMillis(); } +#ifdef TEST + else if (0 == nxagentOption(SleepTime)) { + fprintf(stderr, "nxagentBlockHandler: not sleeping for slowdown.\n"); + } +#endif /* * Update the shadow display. This is @@ -743,9 +744,17 @@ void nxagentShadowBlockHandler(void * data, struct timeval **timeout, void * mas nxagentHandleConnectionChanges(); } - if (nxagentSessionState == SESSION_DOWN) + if (nxagentSessionState == SESSION_DOWN && nxagentOption(SleepTime) > 0) { - usleep(50 * 1000); +#ifdef TEST + fprintf(stderr, "nxagentBlockHandler: sleeping for %d milliseconds for slowdown.\n", + nxagentOption(SleepTime)); +#endif + usleep(nxagentOption(SleepTime) * 1000); + } +#ifdef TEST + else if (0 == nxagentOption(SleepTime)) { + fprintf(stderr, "nxagentBlockHandler: not sleeping for slowdown.\n"); } #ifndef __CYGWIN32__ @@ -826,7 +835,18 @@ FIXME: Must queue multiple writes and handle #ifdef __CYGWIN32__ - usleep(50 * 1000); + if (nxagentOption(SleepTime) > 0) { +#ifdef TEST + fprintf(stderr, "nxagentShadowBlockHandler: sleeping for %d milliseconds for slowdown.\n", + nxagentOption(SleepTime)); +#endif + usleep(nxagentOption(SleepTime) * 1000); + } +#ifdef TEST + else if (0 == nxagentOption(SleepTime)) { + fprintf(stderr, "nxagentShadowBlockHandler: not sleeping for slowdown.\n"); + } +#endif (*timeout) -> tv_sec = 0; (*timeout) -> tv_usec = 50 * 1000; diff --git a/nx-X11/programs/Xserver/hw/nxagent/Image.c b/nx-X11/programs/Xserver/hw/nxagent/Image.c index 6a7d46c35..a158a11db 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Image.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Image.c @@ -68,15 +68,6 @@ #define IMAGE_UNIQUE_RATIO 10 -/* - * Introduce a small delay after each image - * operation if the session is down. Value - * is in microseconds and is multiplied by - * the image data size in kilobytes. - */ - -#define IMAGE_DELAY_IF_DOWN 250 - /* * Preferred pack and split parameters we * got from the NX transport. @@ -521,11 +512,12 @@ void nxagentPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, length = nxagentImageLength(dstWidth, dstHeight, format, leftPad, depth); if (nxagentShadowCounter == 0 && - NXDisplayError(nxagentDisplay) == 1) + NXDisplayError(nxagentDisplay) == 1 && + nxagentOption(SleepTime) > 0) { int us; - us = IMAGE_DELAY_IF_DOWN * (length / 1024); + us = nxagentOption(SleepTime) * 4 * (length / 1024); us = (us < 10000 ? 10000 : (us > 1000000 ? 1000000 : us)); diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.c b/nx-X11/programs/Xserver/hw/nxagent/Options.c index dbe200273..8a3275c64 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Options.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Options.c @@ -156,6 +156,8 @@ void nxagentInitOptions() nxagentOptions.ImageRateLimit = 0; nxagentOptions.Xinerama = 0; + + nxagentOptions.SleepTime = DEFAULT_SLEEP_TIME; } /* diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.h b/nx-X11/programs/Xserver/hw/nxagent/Options.h index 5bf1597d5..02b886242 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Options.h +++ b/nx-X11/programs/Xserver/hw/nxagent/Options.h @@ -28,6 +28,7 @@ #define UNDEFINED -1 #define COPY_UNLIMITED -1 +#define DEFAULT_SLEEP_TIME 50 extern unsigned int nxagentPrintGeometryFlags; @@ -399,6 +400,12 @@ typedef struct _AgentOptions int Xinerama; + /* + * Sleep delay in microseconds. + */ + + unsigned int SleepTime; + } AgentOptionsRec; typedef AgentOptionsRec *AgentOptionsPtr; diff --git a/nxcomp/Loop.cpp b/nxcomp/Loop.cpp index 473488593..5086db012 100644 --- a/nxcomp/Loop.cpp +++ b/nxcomp/Loop.cpp @@ -9003,7 +9003,8 @@ int ParseEnvironmentOptions(const char *env, int force) strcasecmp(name, "keyboard") == 0 || strcasecmp(name, "clipboard") == 0 || strcasecmp(name, "streaming") == 0 || - strcasecmp(name, "backingstore") == 0) + strcasecmp(name, "backingstore") == 0 || + strcasecmp(name, "sleep") == 0) { #ifdef DEBUG *logofs << "Loop: Ignoring agent option '" << name diff --git a/nxcomp/Misc.cpp b/nxcomp/Misc.cpp index ee73f19d8..05794bded 100644 --- a/nxcomp/Misc.cpp +++ b/nxcomp/Misc.cpp @@ -316,7 +316,8 @@ shadowuid=n\n\ shadowmode=s\n\ defer=n\n\ tile=s\n\ -menu=n These options are interpreted by the NX agent. They\n\ +menu=n\n\ +sleep=n These options are interpreted by the NX agent. They\n\ are ignored by the proxy.\n\ \n\ Environment:\n\ -- cgit v1.2.3 From d130494039d7a03aea25c911522223f60c159644 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Fri, 10 Jun 2016 01:05:58 +0200 Subject: Properly enable/disable Xinerama support in nxagent via cmdline options provider in Xserver/os/utils.c. * Xinerama defaults to enabled, using RRXineramaExtension (i.e. cmdline option: +rrxinerama). * Cmdline option -rrxinerama disables Xinerama support entirely. * Cmdline option +xinerama switches from RRXineramaExtension to PanoramiXExtension. * Cmdline option -xinerama is actually non-functional (i.e. the default). * If the nx/nx option "xinerama" is handed over to nxagent, then Xinerama is only switched on if that given option enables it (value: 1) _and_ if either of the Xinerama extensions (PanoramiX or RRXinerama) has been initialized (via cmdline options above). Fixes ArcticaProject/nx-libs#117. Fixes ArcticaProject/nx-libs#134 (makes flawed PR#134 obsolete). --- nx-X11/programs/Xserver/hw/nxagent/Args.c | 62 ++++++++++++++++++---------- nx-X11/programs/Xserver/hw/nxagent/Options.c | 2 +- nx-X11/programs/Xserver/hw/nxagent/Options.h | 12 +++--- nx-X11/programs/Xserver/hw/nxagent/Screen.c | 5 --- 4 files changed, 48 insertions(+), 33 deletions(-) (limited to 'nx-X11/programs/Xserver/hw') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.c b/nx-X11/programs/Xserver/hw/nxagent/Args.c index 2590dd6c3..6e6d61772 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Args.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Args.c @@ -86,6 +86,18 @@ is" without express or implied warranty. #endif +#ifdef PANORAMIX + #define PANORAMIX_DISABLED_COND (noPanoramiXExtension || PanoramiXExtensionDisabledHack) +#else + #define PANORAMIX_DISABLED_COND TRUE +#endif + +#ifdef RANDR + #define RRXINERAMA_DISABLED_COND noRRXineramaExtension +#else + #define RRXINERAMA_DISABLED_COND TRUE +#endif + /* * Define this to force the dispatcher * to always use the dumb scheduler. @@ -103,6 +115,8 @@ extern int _XGetBitsPerPixel(Display *dpy, int depth); extern char dispatchExceptionAtReset; +extern const char *__progname; + char nxagentDisplayName[1024]; Bool nxagentSynchronize = False; @@ -1047,6 +1061,13 @@ int ddxProcessArgument(int argc, char *argv[], int i) return 0; } + /* + * Disable Xinerama (i.e. fake it in Screen.c) if somehow Xinerama support + * has been disabled on the cmdline. + */ + if (PANORAMIX_DISABLED_COND && RRXINERAMA_DISABLED_COND) + nxagentChangeOption(Xinerama, 0); + return 0; } @@ -1205,33 +1226,32 @@ static void nxagentParseOptions(char *name, char *value) } else if (!strcmp(name, "xinerama")) { -#ifdef PANORAMIX - if (!PanoramiXExtensionDisabledHack) +#if !defined(PANORAMIX) && !defined(RANDR) + nxagentChangeOption(Xinerama, 0); + fprintf(stderr, "Warning: No Xinerama support compiled into %s.\n", __progname); + return; +#else + if (PANORAMIX_DISABLED_COND && RRXINERAMA_DISABLED_COND) + nxagentChangeOption(Xinerama, 0); + fprintf(stderr, "Warning: XINERAMA extension has been disabled on %s startup.\n", __progname); + return; + + if (!strcmp(value, "1")) { - if (!strcmp(value, "1")) - { - nxagentChangeOption(Xinerama, 1); - } - else if (!strcmp(value, "0")) - { - nxagentChangeOption(Xinerama, 0); - } - else - { - fprintf(stderr, "Warning: Ignoring bad value '%s' for option 'xinerama'.\n", - validateString(value)); - } + nxagentChangeOption(Xinerama, 1); + return; } - else + else if (!strcmp(value, "0")) { nxagentChangeOption(Xinerama, 0); - fprintf(stderr, "Warning: Xinerama extension has been disabled via -disablexineramaextension cmdline switch.\n"); } -#else - nxagentChangeOption(Xinerama, 0); - fprintf(stderr, "Warning: No Xinerama support compiled into nxagent.\n"); -#endif /* of PANORAMIX */ + else + { + fprintf(stderr, "Warning: Ignoring bad value '%s' for option 'xinerama'.\n", + validateString(value)); + } return; +#endif } else if (!strcmp(name, "resize")) { diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.c b/nx-X11/programs/Xserver/hw/nxagent/Options.c index 8a3275c64..d0ba8aff5 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Options.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Options.c @@ -155,7 +155,7 @@ void nxagentInitOptions() nxagentOptions.ImageRateLimit = 0; - nxagentOptions.Xinerama = 0; + nxagentOptions.Xinerama = 1; nxagentOptions.SleepTime = DEFAULT_SLEEP_TIME; } diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.h b/nx-X11/programs/Xserver/hw/nxagent/Options.h index 02b886242..7e9f8d2ea 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Options.h +++ b/nx-X11/programs/Xserver/hw/nxagent/Options.h @@ -390,12 +390,12 @@ typedef struct _AgentOptions int NoRootlessExit; /* - * Store if the user wants Xinerama. There's a variable called - * noPanoramiXExtension in os/utils.c but we cannot rely on that - * because RandR and Panoramix change its value when trying to - * initialize. So we use this variable to save the user preference - * provided by the -/+xinerama parameter before initalizing those - * extensions. + * Store if the user wants Xinerama. There are variables called + * noPanoramiXExtension noRRXineramaExtensison in os/utils.c but + * we cannot rely on them because RandR and PanoramiX change their + * values when trying to initialize. So we use this variable to + * save the user preference provided by the -/+(rr)xinerama parameter(s) + * before initalizing those extensions. */ int Xinerama; diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index 20ec3672a..50d278ed7 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -1114,11 +1114,6 @@ Bool nxagentOpenScreen(int index, ScreenPtr pScreen, nxagentChangeOption(ViewportXSpan, nxagentOption(Width) - nxagentOption(RootWidth)); nxagentChangeOption(ViewportYSpan, nxagentOption(Height) - nxagentOption(RootHeight)); - /* PanoramiXExtension enabled via cmdline, turn on Xinerama in nxagent - */ - if( (!noPanoramiXExtension) && (!PanoramiXExtensionDisabledHack) ) - nxagentOption(Xinerama) = True; - if (nxagentReconnectTrap == 0) { if (nxagentOption(Persistent)) -- cgit v1.2.3 From 9de3d26efbb5859b5d48bca35e126fc8a44dac1f Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Sat, 18 Jun 2016 19:50:10 +0200 Subject: hw/nxagent/Options.h: Grammar fix in comment. --- nx-X11/programs/Xserver/hw/nxagent/Options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nx-X11/programs/Xserver/hw') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.h b/nx-X11/programs/Xserver/hw/nxagent/Options.h index 7e9f8d2ea..257a332f2 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Options.h +++ b/nx-X11/programs/Xserver/hw/nxagent/Options.h @@ -391,7 +391,7 @@ typedef struct _AgentOptions /* * Store if the user wants Xinerama. There are variables called - * noPanoramiXExtension noRRXineramaExtensison in os/utils.c but + * noPanoramiXExtension and noRRXineramaExtensison in os/utils.c but * we cannot rely on them because RandR and PanoramiX change their * values when trying to initialize. So we use this variable to * save the user preference provided by the -/+(rr)xinerama parameter(s) -- cgit v1.2.3 From 3db9a757fc54d94707aabe4d934d693c6b32edff Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Tue, 21 Jun 2016 03:56:29 +0200 Subject: hw/nxagent/Handlers.c: Regression fix since 6051dec. Close unclosed '#ifdef TEST'. --- nx-X11/programs/Xserver/hw/nxagent/Handlers.c | 1 + 1 file changed, 1 insertion(+) (limited to 'nx-X11/programs/Xserver/hw') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c index ba4034255..62cc54990 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c @@ -756,6 +756,7 @@ void nxagentShadowBlockHandler(void * data, struct timeval **timeout, void * mas else if (0 == nxagentOption(SleepTime)) { fprintf(stderr, "nxagentBlockHandler: not sleeping for slowdown.\n"); } +#endif #ifndef __CYGWIN32__ -- cgit v1.2.3 From 560fd4e5f9ab33a92776d0de512e551f2895994f Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Mon, 20 Jun 2016 11:21:46 +0200 Subject: nxagent/hw/NXextension.c: Allow CloseDownProc to be NULL. Required code de-duplication in nxagent. (Will be fixed by ArcticaProject/nx-libs#120 later on). --- nx-X11/programs/Xserver/hw/nxagent/NXextension.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'nx-X11/programs/Xserver/hw') diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c index 962367bf2..0c0145477 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c +++ b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c @@ -111,7 +111,7 @@ AddExtension(char *name, int NumEvents, int NumErrors, int i; register ExtensionEntry *ext, **newexts; - if (!MainProc || !SwappedMainProc || !CloseDownProc || !MinorOpcodeProc) + if (!MainProc || !SwappedMainProc || !MinorOpcodeProc) return((ExtensionEntry *) NULL); if ((lastEvent + NumEvents > LAST_EVENT) || (unsigned)(lastError + NumErrors > LAST_ERROR)) @@ -296,7 +296,8 @@ CloseDownExtensions() for (i = NumExtensions - 1; i >= 0; i--) { - (* extensions[i]->CloseDown)(extensions[i]); + if (extensions[i]->CloseDown) + (* extensions[i]->CloseDown)(extensions[i]); NumExtensions = i; xfree(extensions[i]->name); for (j = extensions[i]->num_aliases; --j >= 0;) -- cgit v1.2.3 From c61bb8cc59bf645f1bf4dbc5fd5464d559b3ecad Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Mon, 20 Jun 2016 12:18:53 +0200 Subject: Move each screen's root-window pointer into ScreenRec. Backported from X.org: commit e7fae9ecc42ab5e73b89117722dbf4117d928f9a Author: Jamey Sharp Date: Sat May 22 00:26:28 2010 -0700 Move each screen's root-window pointer into ScreenRec. Many references to the WindowTable array already had the corresponding screen pointer handy, which meant they usually looked like "WindowTable[pScreen->myNum]". Adding a field to ScreenRec instead of keeping this information in a parallel array simplifies those expressions, and eliminates a MAXSCREENS-sized array. Since dix uses this data, a screen private entry isn't appropriate. xf86-video-dummy currently uses WindowTable, so it needs to be updated to reflect this change. Signed-off-by: Jamey Sharp Reviewed-by: Tiago Vignatti Tested-by: Tiago Vignatti (i686 GNU/Linux) Backport to nx-libs: Mike Gabriel --- nx-X11/programs/Xserver/Xext/panoramiX.c | 2 +- nx-X11/programs/Xserver/Xext/panoramiX.h | 4 +- nx-X11/programs/Xserver/Xext/panoramiXprocs.c | 14 +++---- nx-X11/programs/Xserver/Xext/saver.c | 6 +-- nx-X11/programs/Xserver/Xext/xtest.c | 2 +- nx-X11/programs/Xserver/Xi/chgptr.c | 2 +- nx-X11/programs/Xserver/Xi/closedev.c | 2 +- nx-X11/programs/Xserver/composite/compalloc.c | 2 +- nx-X11/programs/Xserver/composite/compoverlay.c | 2 +- nx-X11/programs/Xserver/dix/dispatch.c | 16 ++++---- nx-X11/programs/Xserver/dix/events.c | 45 +++++++++++----------- nx-X11/programs/Xserver/dix/globals.c | 2 - nx-X11/programs/Xserver/dix/main.c | 18 ++++----- nx-X11/programs/Xserver/dix/resource.c | 8 ++-- nx-X11/programs/Xserver/dix/window.c | 20 +++++----- nx-X11/programs/Xserver/fb/fb.h | 5 +-- nx-X11/programs/Xserver/fb/fbwindow.c | 2 +- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 9 +++-- nx-X11/programs/Xserver/hw/nxagent/Composite.c | 2 +- nx-X11/programs/Xserver/hw/nxagent/Drawable.c | 2 +- nx-X11/programs/Xserver/hw/nxagent/Events.c | 30 +++++++-------- nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c | 20 +++++----- nx-X11/programs/Xserver/hw/nxagent/NXevents.c | 50 ++++++++++++------------- nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c | 4 +- nx-X11/programs/Xserver/hw/nxagent/NXrender.c | 2 +- nx-X11/programs/Xserver/hw/nxagent/NXresource.c | 8 ++-- nx-X11/programs/Xserver/hw/nxagent/NXwindow.c | 30 ++++++++------- nx-X11/programs/Xserver/hw/nxagent/Pixmap.c | 2 +- nx-X11/programs/Xserver/hw/nxagent/Rootless.c | 13 ++++--- nx-X11/programs/Xserver/hw/nxagent/Screen.c | 42 ++++++++++----------- nx-X11/programs/Xserver/hw/nxagent/Splash.c | 6 +-- nx-X11/programs/Xserver/hw/nxagent/Window.c | 42 ++++++++++----------- nx-X11/programs/Xserver/hw/nxagent/Windows.h | 2 +- nx-X11/programs/Xserver/include/globals.h | 1 - nx-X11/programs/Xserver/include/scrnintstr.h | 1 + nx-X11/programs/Xserver/mi/mibank.c | 6 +-- nx-X11/programs/Xserver/mi/midispcur.c | 10 ++--- nx-X11/programs/Xserver/mi/miexpose.c | 4 +- nx-X11/programs/Xserver/mi/mioverlay.c | 4 +- nx-X11/programs/Xserver/render/render.c | 2 +- nx-X11/programs/Xserver/xfixes/cursor.c | 2 +- nx-X11/programs/Xserver/xkb/xkbInit.c | 3 +- 42 files changed, 225 insertions(+), 224 deletions(-) (limited to 'nx-X11/programs/Xserver/hw') diff --git a/nx-X11/programs/Xserver/Xext/panoramiX.c b/nx-X11/programs/Xserver/Xext/panoramiX.c index 2671ba0d3..9c5eefe4a 100644 --- a/nx-X11/programs/Xserver/Xext/panoramiX.c +++ b/nx-X11/programs/Xserver/Xext/panoramiX.c @@ -896,7 +896,7 @@ void PanoramiXConsolidate(void) for (i = 0; i < PanoramiXNumScreens; i++) { - root->info[i].id = WindowTable[i]->drawable.id; + root->info[i].id = screenInfo.screens[i]->root->drawable.id; root->u.win.class = InputOutput; root->u.win.root = TRUE; saver->info[i].id = savedScreenInfo[i].wid; diff --git a/nx-X11/programs/Xserver/Xext/panoramiX.h b/nx-X11/programs/Xserver/Xext/panoramiX.h index 3f70b6473..8113e3072 100644 --- a/nx-X11/programs/Xserver/Xext/panoramiX.h +++ b/nx-X11/programs/Xserver/Xext/panoramiX.h @@ -89,11 +89,11 @@ typedef struct { #define FORCE_ROOT(a) { \ int _j; \ for (_j = PanoramiXNumScreens - 1; _j; _j--) \ - if ((a).root == WindowTable[_j]->drawable.id) \ + if ((a).root == screenInfo.screens[_j]->root->drawable.id) \ break; \ (a).rootX += panoramiXdataPtr[_j].x; \ (a).rootY += panoramiXdataPtr[_j].y; \ - (a).root = WindowTable[0]->drawable.id; \ + (a).root = screenInfo.screens[0]->root->drawable.id; \ } #define FORCE_WIN(a) { \ diff --git a/nx-X11/programs/Xserver/Xext/panoramiXprocs.c b/nx-X11/programs/Xserver/Xext/panoramiXprocs.c index 17fe6d6c6..b4719d76f 100644 --- a/nx-X11/programs/Xserver/Xext/panoramiXprocs.c +++ b/nx-X11/programs/Xserver/Xext/panoramiXprocs.c @@ -146,7 +146,7 @@ int PanoramiXCreateWindow(ClientPtr client) orig_visual = stuff->visual; orig_x = stuff->x; orig_y = stuff->y; - parentIsRoot = (stuff->parent == WindowTable[0]->drawable.id) || + parentIsRoot = (stuff->parent == screenInfo.screens[0]->root->drawable.id) || (stuff->parent == savedScreenInfo[0].wid); FOR_NSCREENS_BACKWARD(j) { stuff->wid = newWin->info[j].id; @@ -336,7 +336,7 @@ int PanoramiXReparentWindow(ClientPtr client) x = stuff->x; y = stuff->y; - parentIsRoot = (stuff->parent == WindowTable[0]->drawable.id) || + parentIsRoot = (stuff->parent == screenInfo.screens[0]->root->drawable.id) || (stuff->parent == savedScreenInfo[0].wid); FOR_NSCREENS_BACKWARD(j) { stuff->window = win->info[j].id; @@ -476,7 +476,7 @@ int PanoramiXConfigureWindow(ClientPtr client) } } - if(pWin->parent && ((pWin->parent == WindowTable[0]) || + if(pWin->parent && ((pWin->parent == screenInfo.screens[0]->root) || (pWin->parent->drawable.id == savedScreenInfo[0].wid))) { if ((Mask)stuff->mask & CWX) { @@ -540,7 +540,7 @@ int PanoramiXGetGeometry(ClientPtr client) rep.type = X_Reply; rep.length = 0; rep.sequenceNumber = client->sequence; - rep.root = WindowTable[0]->drawable.id; + rep.root = screenInfo.screens[0]->root->drawable.id; rep.depth = pDraw->depth; rep.width = pDraw->width; rep.height = pDraw->height; @@ -558,7 +558,7 @@ int PanoramiXGetGeometry(ClientPtr client) WindowPtr pWin = (WindowPtr)pDraw; rep.x = pWin->origin.x - wBorderWidth (pWin); rep.y = pWin->origin.y - wBorderWidth (pWin); - if((pWin->parent == WindowTable[0]) || + if((pWin->parent == screenInfo.screens[0]->root) || (pWin->parent->drawable.id == savedScreenInfo[0].wid)) { rep.x += panoramiXdataPtr[0].x; @@ -594,7 +594,7 @@ int PanoramiXTranslateCoords(ClientPtr client) rep.sameScreen = xTrue; rep.child = None; - if((pWin == WindowTable[0]) || + if((pWin == screenInfo.screens[0]->root) || (pWin->drawable.id == savedScreenInfo[0].wid)) { x = stuff->srcX - panoramiXdataPtr[0].x; @@ -636,7 +636,7 @@ int PanoramiXTranslateCoords(ClientPtr client) } rep.dstX = x - pDst->drawable.x; rep.dstY = y - pDst->drawable.y; - if((pDst == WindowTable[0]) || + if((pDst == screenInfo.screens[0]->root) || (pDst->drawable.id == savedScreenInfo[0].wid)) { rep.dstX += panoramiXdataPtr[0].x; diff --git a/nx-X11/programs/Xserver/Xext/saver.c b/nx-X11/programs/Xserver/Xext/saver.c index ec91d080a..a871be9b7 100644 --- a/nx-X11/programs/Xserver/Xext/saver.c +++ b/nx-X11/programs/Xserver/Xext/saver.c @@ -473,7 +473,7 @@ SendScreenSaverNotify (pScreen, state, forced) ev.state = state; ev.sequenceNumber = client->sequence; ev.timestamp = currentTime.milliseconds; - ev.root = WindowTable[pScreen->myNum]->drawable.id; + ev.root = pScreen->root->drawable.id; ev.window = savedScreenInfo[pScreen->myNum].wid; ev.kind = kind; ev.forced = forced; @@ -549,7 +549,7 @@ CreateSaverWindow (pScreen) if (GrabInProgress && GrabInProgress != pAttr->client->index) return FALSE; - pWin = CreateWindow (pSaver->wid, WindowTable[pScreen->myNum], + pWin = CreateWindow (pSaver->wid, pScreen->root, pAttr->x, pAttr->y, pAttr->width, pAttr->height, pAttr->borderWidth, pAttr->class, pAttr->mask, (XID *)pAttr->values, @@ -830,7 +830,7 @@ ScreenSaverSetAttributes (ClientPtr client) if (!pDraw) return BadDrawable; pScreen = pDraw->pScreen; - pParent = WindowTable[pScreen->myNum]; + pParent = pScreen->root; len = stuff->length - (sizeof(xScreenSaverSetAttributesReq) >> 2); if (Ones(stuff->mask) != len) diff --git a/nx-X11/programs/Xserver/Xext/xtest.c b/nx-X11/programs/Xserver/Xext/xtest.c index 8a03db5f9..565e8e8d7 100644 --- a/nx-X11/programs/Xserver/Xext/xtest.c +++ b/nx-X11/programs/Xserver/Xext/xtest.c @@ -409,7 +409,7 @@ ProcXTestFakeInput(client) if (RegionContainsPoint( &XineramaScreenRegions[i], x, y, &box)) { - root = WindowTable[i]; + root = screenInfo.screens[i]->root; x -= panoramiXdataPtr[i].x; y -= panoramiXdataPtr[i].y; ev->u.keyButtonPointer.rootX = x; diff --git a/nx-X11/programs/Xserver/Xi/chgptr.c b/nx-X11/programs/Xserver/Xi/chgptr.c index 925d43c07..4877fcc84 100644 --- a/nx-X11/programs/Xserver/Xi/chgptr.c +++ b/nx-X11/programs/Xserver/Xi/chgptr.c @@ -208,7 +208,7 @@ SendEventToAllWindows (dev, mask, ev, count) for (i=0; iroot; (void)DeliverEventsToWindow(pWin, ev, count, mask, NullGrab, dev->id); p1 = pWin->firstChild; FindInterestedChildren (dev, p1, mask, ev, count); diff --git a/nx-X11/programs/Xserver/Xi/closedev.c b/nx-X11/programs/Xserver/Xi/closedev.c index ae46f50c6..5f90b57a4 100644 --- a/nx-X11/programs/Xserver/Xi/closedev.c +++ b/nx-X11/programs/Xserver/Xi/closedev.c @@ -124,7 +124,7 @@ ProcXCloseDevice(client) for (i=0; iroot; DeleteDeviceEvents (d, pWin, client); p1 = pWin->firstChild; DeleteEventsFromChildren (d, p1, client); diff --git a/nx-X11/programs/Xserver/composite/compalloc.c b/nx-X11/programs/Xserver/composite/compalloc.c index 9279a5248..017459b6b 100644 --- a/nx-X11/programs/Xserver/composite/compalloc.c +++ b/nx-X11/programs/Xserver/composite/compalloc.c @@ -32,7 +32,7 @@ static void compScreenUpdate(ScreenPtr pScreen) { compCheckTree(pScreen); - compPaintChildrenToWindow(pScreen, WindowTable[pScreen->myNum]); + compPaintChildrenToWindow(pScreen, pScreen->root); } static void diff --git a/nx-X11/programs/Xserver/composite/compoverlay.c b/nx-X11/programs/Xserver/composite/compoverlay.c index dfe59f3cf..226bbcb6a 100644 --- a/nx-X11/programs/Xserver/composite/compoverlay.c +++ b/nx-X11/programs/Xserver/composite/compoverlay.c @@ -129,7 +129,7 @@ Bool compCreateOverlayWindow(ScreenPtr pScreen) { CompScreenPtr cs = GetCompScreen(pScreen); - WindowPtr pRoot = WindowTable[pScreen->myNum]; + WindowPtr pRoot = pScreen->root; WindowPtr pWin; XID attrs[] = { None, TRUE }; /* backPixmap, overrideRedirect */ int result; diff --git a/nx-X11/programs/Xserver/dix/dispatch.c b/nx-X11/programs/Xserver/dix/dispatch.c index a76c0723c..66671d1f4 100644 --- a/nx-X11/programs/Xserver/dix/dispatch.c +++ b/nx-X11/programs/Xserver/dix/dispatch.c @@ -234,8 +234,8 @@ FlushClientCaches(XID id) { if (client->lastDrawableID == id) { - client->lastDrawableID = WindowTable[0]->drawable.id; - client->lastDrawable = (DrawablePtr)WindowTable[0]; + client->lastDrawableID = screenInfo.screens[0]->root->drawable.id; + client->lastDrawable = (DrawablePtr)screenInfo.screens[0]->root; } else if (client->lastGCID == id) { @@ -793,7 +793,7 @@ GetGeometry(register ClientPtr client, xGetGeometryReply *rep) rep->type = X_Reply; rep->length = 0; rep->sequenceNumber = client->sequence; - rep->root = WindowTable[pDraw->pScreen->myNum]->drawable.id; + rep->root = pDraw->pScreen->root->drawable.id; rep->depth = pDraw->depth; rep->width = pDraw->width; rep->height = pDraw->height; @@ -854,7 +854,7 @@ ProcQueryTree(register ClientPtr client) return(BadWindow); memset(&reply, 0, sizeof(xQueryTreeReply)); reply.type = X_Reply; - reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id; + reply.root = pWin->drawable.pScreen->root->drawable.id; reply.sequenceNumber = client->sequence; if (pWin->parent) reply.parent = pWin->parent->drawable.id; @@ -3633,8 +3633,8 @@ void InitClient(ClientPtr client, int i, void * ospriv) if (i) { client->closeDownMode = DestroyAll; - client->lastDrawable = (DrawablePtr)WindowTable[0]; - client->lastDrawableID = WindowTable[0]->drawable.id; + client->lastDrawable = (DrawablePtr)screenInfo.screens[0]->root; + client->lastDrawableID = screenInfo.screens[0]->root->drawable.id; } else { @@ -3853,8 +3853,8 @@ SendConnSetup(register ClientPtr client, char *reason) register unsigned int j; register xDepth *pDepth; - root->currentInputMask = WindowTable[i]->eventMask | - wOtherEventMasks (WindowTable[i]); + root->currentInputMask = screenInfo.screens[i]->root->eventMask | + wOtherEventMasks (screenInfo.screens[i]->root); pDepth = (xDepth *)(root + 1); for (j = 0; j < root->nDepths; j++) { diff --git a/nx-X11/programs/Xserver/dix/events.c b/nx-X11/programs/Xserver/dix/events.c index 9005cd226..8f943887a 100644 --- a/nx-X11/programs/Xserver/dix/events.c +++ b/nx-X11/programs/Xserver/dix/events.c @@ -413,9 +413,10 @@ XineramaCheckPhysLimits( static Bool XineramaSetWindowPntrs(WindowPtr pWin) { - if(pWin == WindowTable[0]) { - memcpy(sprite.windows, WindowTable, - PanoramiXNumScreens*sizeof(WindowPtr)); + if(pWin == screenInfo.screens[0]->root) { + int i; + for (i = 0; i < PanoramiXNumScreens; i++) + sprite.windows[i] = screenInfo.screens[i]->root; } else { PanoramiXRes *win; int i; @@ -601,7 +602,7 @@ XineramaConfineCursorToWindow(WindowPtr pWin, Bool generateEvents) sprite.hotShape = NullRegion; sprite.confined = FALSE; - sprite.confineWin = (pWin == WindowTable[0]) ? NullWindow : pWin; + sprite.confineWin = (pWin == screenInfo.screens[0]->root) ? NullWindow : pWin; XineramaCheckPhysLimits(sprite.current, generateEvents); } @@ -797,7 +798,7 @@ CheckVirtualMotion( qe->event->u.keyButtonPointer.rootY = sprite.hot.y; } } - ROOT = WindowTable[sprite.hot.pScreen->myNum]; + ROOT = sprite.hot.pScreen->root; } static void @@ -997,7 +998,7 @@ EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count) */ if (xE->u.u.type == MotionNotify) XE_KBPTR.root = - WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id; + sprite.hotPhys.pScreen->root->drawable.id; eventinfo.events = xE; eventinfo.count = count; CallCallbacks(&DeviceEventCallback, (void *)&eventinfo); @@ -1160,7 +1161,7 @@ playmore: ConfineCursorToWindow(grab->confineTo, TRUE, TRUE); } else - ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum], + ConfineCursorToWindow(sprite.hotPhys.pScreen->root, TRUE, FALSE); PostNewCursor(); } @@ -1178,7 +1179,7 @@ ScreenRestructured (ScreenPtr pScreen) ConfineCursorToWindow(grab->confineTo, TRUE, TRUE); } else - ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum], + ConfineCursorToWindow(sprite.hotPhys.pScreen->root, TRUE, FALSE); } #endif @@ -1976,7 +1977,7 @@ CheckMotion(xEvent *xE) if (sprite.hot.pScreen != sprite.hotPhys.pScreen) { sprite.hot.pScreen = sprite.hotPhys.pScreen; - ROOT = WindowTable[sprite.hot.pScreen->myNum]; + ROOT = sprite.hot.pScreen->root; } sprite.hot.x = XE_KBPTR.rootX; sprite.hot.y = XE_KBPTR.rootY; @@ -2034,7 +2035,7 @@ WindowsRestructured() #ifdef PANORAMIX /* This was added to support reconfiguration under Xdmx. The problem is - * that if the 0th screen (i.e., WindowTable[0]) is moved to an origin + * that if the 0th screen (i.e., screenInfo.screens[0]->root) is moved to an origin * other than 0,0, the information in the private sprite structure must * be updated accordingly, or XYToWindow (and other routines) will not * compute correctly. */ @@ -2067,7 +2068,7 @@ void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff) sprite.hotPhys.x = sprite.hotPhys.y = 0; ConfineCursorToWindow(grab->confineTo, TRUE, TRUE); } else - ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum], + ConfineCursorToWindow(sprite.hotPhys.pScreen->root, TRUE, FALSE); } #endif @@ -2144,7 +2145,7 @@ NewCurrentScreen(ScreenPtr newScreen, int x, int y) if(sprite.confineWin) XineramaConfineCursorToWindow(sprite.confineWin, TRUE); else - XineramaConfineCursorToWindow(WindowTable[0], TRUE); + XineramaConfineCursorToWindow(screenInfo.screens[0]->root, TRUE); /* if the pointer wasn't confined, the DDX won't get told of the pointer warp so we reposition it here */ if(!syncEvents.playingEvents) @@ -2157,7 +2158,7 @@ NewCurrentScreen(ScreenPtr newScreen, int x, int y) } else #endif if (newScreen != sprite.hotPhys.pScreen) - ConfineCursorToWindow(WindowTable[newScreen->myNum], TRUE, FALSE); + ConfineCursorToWindow(newScreen->root, TRUE, FALSE); } #ifdef PANORAMIX @@ -2231,7 +2232,7 @@ XineramaWarpPointer(ClientPtr client) winX = source->drawable.x; winY = source->drawable.y; - if(source == WindowTable[0]) { + if(source == screenInfo.screens[0]->root) { winX -= panoramiXdataPtr[0].x; winY -= panoramiXdataPtr[0].y; } @@ -2247,7 +2248,7 @@ XineramaWarpPointer(ClientPtr client) if (dest) { x = dest->drawable.x; y = dest->drawable.y; - if(dest == WindowTable[0]) { + if(dest == screenInfo.screens[0]->root) { x -= panoramiXdataPtr[0].x; y -= panoramiXdataPtr[0].y; } @@ -2822,7 +2823,7 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count /* see comment in EnqueueEvents regarding the next three lines */ if (xE->u.u.type == MotionNotify) XE_KBPTR.root = - WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id; + sprite.hotPhys.pScreen->root->drawable.id; eventinfo.events = xE; eventinfo.count = count; CallCallbacks(&DeviceEventCallback, (void *)&eventinfo); @@ -3356,11 +3357,11 @@ DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode) /* Notify all the roots */ #ifdef PANORAMIX if ( !noPanoramiXExtension ) - FocusEvent(dev, FocusOut, mode, out, WindowTable[0]); + FocusEvent(dev, FocusOut, mode, out, screenInfo.screens[0]->root); else #endif for (i=0; iroot); } else { @@ -3375,11 +3376,11 @@ DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode) /* Notify all the roots */ #ifdef PANORAMIX if ( !noPanoramiXExtension ) - FocusEvent(dev, FocusIn, mode, in, WindowTable[0]); + FocusEvent(dev, FocusIn, mode, in, screenInfo.screens[0]->root); else #endif for (i=0; iroot); if (toWin == PointerRootWin) (void)FocusInEvents(dev, ROOT, sprite.win, NullWindow, mode, NotifyPointer, TRUE); @@ -3393,11 +3394,11 @@ DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode) TRUE); #ifdef PANORAMIX if ( !noPanoramiXExtension ) - FocusEvent(dev, FocusOut, mode, out, WindowTable[0]); + FocusEvent(dev, FocusOut, mode, out, screenInfo.screens[0]->root); else #endif for (i=0; iroot); if (toWin->parent != NullWindow) (void)FocusInEvents(dev, ROOT, toWin, toWin, mode, NotifyNonlinearVirtual, TRUE); diff --git a/nx-X11/programs/Xserver/dix/globals.c b/nx-X11/programs/Xserver/dix/globals.c index 9d9e8bfe7..632d0f82b 100644 --- a/nx-X11/programs/Xserver/dix/globals.c +++ b/nx-X11/programs/Xserver/dix/globals.c @@ -86,8 +86,6 @@ ClientPtr serverClient; int currentMaxClients; /* current size of clients array */ long maxBigRequestSize = MAX_BIG_REQUEST_SIZE; -WindowPtr *WindowTable; - unsigned long globalSerialNumber = 0; unsigned long serverGeneration = 0; diff --git a/nx-X11/programs/Xserver/dix/main.c b/nx-X11/programs/Xserver/dix/main.c index 050da899e..25fbb8b65 100644 --- a/nx-X11/programs/Xserver/dix/main.c +++ b/nx-X11/programs/Xserver/dix/main.c @@ -332,9 +332,6 @@ main(int argc, char *argv[], char *envp[]) screenInfo.arraySize = MAXSCREENS; screenInfo.numScreens = 0; screenInfo.numVideoScreens = -1; - WindowTable = (WindowPtr *)xalloc(MAXSCREENS * sizeof(WindowPtr)); - if (!WindowTable) - FatalError("couldn't create root window table"); /* * Just in case the ddx doesnt supply a format for depth 1 (like qvss). @@ -419,8 +416,8 @@ main(int argc, char *argv[], char *envp[]) #endif for (i = 0; i < screenInfo.numScreens; i++) - InitRootWindow(WindowTable[i]); - DefineInitialRootWindow(WindowTable[0]); + InitRootWindow(screenInfo.screens[i]->root); + DefineInitialRootWindow(screenInfo.screens[0]->root); SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset); #ifdef DPMSExtension SetDPMSTimers(); @@ -456,7 +453,11 @@ main(int argc, char *argv[], char *envp[]) FreeAllResources(); #endif + for (i = 0; i < screenInfo.numScreens; i++) + screenInfo.screens[i]->root = NullWindow; CloseDownDevices(); + CloseDownEvents(); + for (i = screenInfo.numScreens - 1; i >= 0; i--) { FreeScratchPixmapsForScreen(i); @@ -466,9 +467,6 @@ main(int argc, char *argv[], char *envp[]) FreeScreen(screenInfo.screens[i]); screenInfo.numScreens = i; } - CloseDownEvents(); - xfree(WindowTable); - WindowTable = NULL; FreeFonts(); #ifdef DPMSExtension @@ -595,7 +593,7 @@ CreateConnectionBlock() VisualPtr pVisual; pScreen = screenInfo.screens[i]; - root.windowId = WindowTable[i]->drawable.id; + root.windowId = screenInfo.screens[i]->root->drawable.id; root.defaultColormap = pScreen->defColormap; root.whitePixel = pScreen->whitePixel; root.blackPixel = pScreen->blackPixel; @@ -769,7 +767,6 @@ AddScreen( multiple screens. */ pScreen->rgf = ~0L; /* there are no scratch GCs yet*/ - WindowTable[i] = NullWindow; screenInfo.screens[i] = pScreen; screenInfo.numScreens++; if (!(*pfnInit)(i, pScreen, argc, argv)) @@ -784,6 +781,7 @@ AddScreen( static void FreeScreen(ScreenPtr pScreen) { + pScreen->root = NullWindow; xfree(pScreen->WindowPrivateSizes); xfree(pScreen->GCPrivateSizes); #ifdef PIXPRIV diff --git a/nx-X11/programs/Xserver/dix/resource.c b/nx-X11/programs/Xserver/dix/resource.c index ed8a255f5..d579b33fa 100644 --- a/nx-X11/programs/Xserver/dix/resource.c +++ b/nx-X11/programs/Xserver/dix/resource.c @@ -544,8 +544,8 @@ FreeResource(XID id, RESTYPE skipDeleteFuncType) } if(clients[cid] && (id == clients[cid]->lastDrawableID)) { - clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0]; - clients[cid]->lastDrawableID = WindowTable[0]->drawable.id; + clients[cid]->lastDrawable = (DrawablePtr)screenInfo.screens[0]->root; + clients[cid]->lastDrawableID = screenInfo.screens[0]->root->drawable.id; } } if (!gotOne) @@ -582,8 +582,8 @@ FreeResourceByType(XID id, RESTYPE type, Bool skipFree) } if(clients[cid] && (id == clients[cid]->lastDrawableID)) { - clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0]; - clients[cid]->lastDrawableID = WindowTable[0]->drawable.id; + clients[cid]->lastDrawable = (DrawablePtr)screenInfo.screens[0]->root; + clients[cid]->lastDrawableID = screenInfo.screens[0]->root->drawable.id; } } } diff --git a/nx-X11/programs/Xserver/dix/window.c b/nx-X11/programs/Xserver/dix/window.c index 6221af4d1..5a4818f88 100644 --- a/nx-X11/programs/Xserver/dix/window.c +++ b/nx-X11/programs/Xserver/dix/window.c @@ -191,7 +191,7 @@ PrintWindowTree() for (i=0; iroot; RegionPrint(&pWin->clipList); p1 = pWin->firstChild; PrintChildren(p1, 4); @@ -237,7 +237,7 @@ TraverseTree(register WindowPtr pWin, VisitWindowProcPtr func, void * data) int WalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, void * data) { - return(TraverseTree(WindowTable[pScreen->myNum], func, data)); + return(TraverseTree(pScreen->root, func, data)); } /* hack for forcing backing store on all windows */ @@ -384,7 +384,7 @@ CreateRootWindow(ScreenPtr pScreen) savedScreenInfo[pScreen->myNum].ExternalScreenSaver = NULL; screenIsSaved = SCREEN_SAVER_OFF; - WindowTable[pScreen->myNum] = pWin; + pScreen->root = pWin; pWin->drawable.pScreen = pScreen; pWin->drawable.type = DRAWABLE_WINDOW; @@ -1348,7 +1348,7 @@ ChangeWindowAttributes(register WindowPtr pWin, Mask vmask, XID *vlist, ClientPt */ if ( cursorID == None) { - if (pWin == WindowTable[pWin->drawable.pScreen->myNum]) + if (pWin == pWin->drawable.pScreen->root) pCursor = rootCursor; else pCursor = (CursorPtr) None; @@ -3088,7 +3088,7 @@ HandleSaveSet(register ClientPtr client) pWin = SaveSetWindow(client->saveSet[j]); #ifdef XFIXES if (SaveSetToRoot(client->saveSet[j])) - pParent = WindowTable[pWin->drawable.pScreen->myNum]; + pParent = pWin->drawable.pScreen->root; else #endif { @@ -3382,9 +3382,9 @@ TileScreenSaver(int i, int kind) attri = 0; switch (kind) { case SCREEN_IS_TILED: - switch (WindowTable[i]->backgroundState) { + switch (screenInfo.screens[i]->root->backgroundState) { case BackgroundPixel: - attributes[attri++] = WindowTable[i]->background.pixel; + attributes[attri++] = screenInfo.screens[i]->root->background.pixel; mask |= CWBackPixel; break; case BackgroundPixmap: @@ -3396,7 +3396,7 @@ TileScreenSaver(int i, int kind) } break; case SCREEN_IS_BLACK: - attributes[attri++] = WindowTable[i]->drawable.pScreen->blackPixel; + attributes[attri++] = screenInfo.screens[i]->root->drawable.pScreen->blackPixel; mask |= CWBackPixel; break; } @@ -3444,12 +3444,12 @@ TileScreenSaver(int i, int kind) pWin = savedScreenInfo[i].pWindow = CreateWindow(savedScreenInfo[i].wid, - WindowTable[i], + screenInfo.screens[i]->root, -RANDOM_WIDTH, -RANDOM_WIDTH, (unsigned short)screenInfo.screens[i]->width + RANDOM_WIDTH, (unsigned short)screenInfo.screens[i]->height + RANDOM_WIDTH, 0, InputOutput, mask, attributes, 0, serverClient, - wVisual (WindowTable[i]), &result); + wVisual (screenInfo.screens[i]->root), &result); if (cursor) FreeResource (cursorID, RT_NONE); diff --git a/nx-X11/programs/Xserver/fb/fb.h b/nx-X11/programs/Xserver/fb/fb.h index 1da5d2470..008ab3ec7 100644 --- a/nx-X11/programs/Xserver/fb/fb.h +++ b/nx-X11/programs/Xserver/fb/fb.h @@ -582,8 +582,7 @@ extern const GCFuncs fbGCFuncs; #endif #ifdef FB_OLD_SCREEN -# define FB_OLD_MISCREENINIT /* miScreenInit requires 14 args, not 13 */ -extern WindowPtr *WindowTable; +# define FB_OLD_MISCREENINIT /* miScreenInit requires 14 args, not 13 */ #endif #ifdef FB_24_32BIT @@ -704,7 +703,7 @@ typedef struct { #define fbWindowEnabled(pWin) \ RegionNotEmpty(\ - &WindowTable[(pWin)->drawable.pScreen->myNum]->borderClip) + &(pWin)->drawable.pScreen->root->borderClip) #define fbDrawableEnabled(pDrawable) \ ((pDrawable)->type == DRAWABLE_PIXMAP ? \ diff --git a/nx-X11/programs/Xserver/fb/fbwindow.c b/nx-X11/programs/Xserver/fb/fbwindow.c index 5ce7ba729..b2df19f0d 100644 --- a/nx-X11/programs/Xserver/fb/fbwindow.c +++ b/nx-X11/programs/Xserver/fb/fbwindow.c @@ -262,7 +262,7 @@ fbFillRegionTiled (DrawablePtr pDrawable, if(!noPanoramiXExtension) { int index = pDrawable->pScreen->myNum; - if(&WindowTable[index]->drawable == pDrawable) + if(&screenInfo.screens[index]->root->drawable == pDrawable) { xRot -= panoramiXdataPtr[index].x; yRot -= panoramiXdataPtr[index].y; diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index f3656d2c0..a0dfbf602 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -22,6 +22,7 @@ #include "Xatom.h" #include "selection.h" #include "windowstr.h" +#include "scrnintstr.h" #include "Windows.h" #include "Atoms.h" @@ -255,7 +256,7 @@ void nxagentClearSelection(XEvent *X) NullGrab); } - CurrentSelections[i].window = WindowTable[0]->drawable.id; + CurrentSelections[i].window = screenInfo.screens[0]->root->drawable.id; CurrentSelections[i].client = NullClient; lastSelectionOwner[i].client = NULL; @@ -424,7 +425,7 @@ FIXME: Do we need this? * Fictitious window. */ - x.u.selectionRequest.requestor = WindowTable[0]->drawable.id; + x.u.selectionRequest.requestor = screenInfo.screens[0]->root->drawable.id; /* * Don't send the same window, some programs are @@ -1502,13 +1503,13 @@ int nxagentInitClipboard(WindowPtr pWin) lastSelectionOwner[nxagentPrimarySelection].selection = XA_PRIMARY; lastSelectionOwner[nxagentPrimarySelection].client = NullClient; - lastSelectionOwner[nxagentPrimarySelection].window = WindowTable[0]->drawable.id; + lastSelectionOwner[nxagentPrimarySelection].window = screenInfo.screens[0]->root->drawable.id; lastSelectionOwner[nxagentPrimarySelection].windowPtr = NULL; lastSelectionOwner[nxagentPrimarySelection].lastTimeChanged = GetTimeInMillis(); lastSelectionOwner[nxagentClipboardSelection].selection = nxagentClipboardAtom; lastSelectionOwner[nxagentClipboardSelection].client = NullClient; - lastSelectionOwner[nxagentClipboardSelection].window = WindowTable[0]->drawable.id; + lastSelectionOwner[nxagentClipboardSelection].window = screenInfo.screens[0]->root->drawable.id; lastSelectionOwner[nxagentClipboardSelection].windowPtr = NULL; lastSelectionOwner[nxagentClipboardSelection].lastTimeChanged = GetTimeInMillis(); diff --git a/nx-X11/programs/Xserver/hw/nxagent/Composite.c b/nx-X11/programs/Xserver/hw/nxagent/Composite.c index ae3cbb5a4..d6239d619 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Composite.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Composite.c @@ -125,7 +125,7 @@ void nxagentRedirectDefaultWindows() for (i = 0; i < screenInfo.numScreens; i++) { - WindowPtr pWin = WindowTable[i]; + WindowPtr pWin = screenInfo.screens[i]->root; ScreenPtr pScreen = pWin -> drawable.pScreen; diff --git a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c index 9dac8066a..377e119ab 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c @@ -3292,7 +3292,7 @@ void nxagentSendDeferredBackgroundExposures(void) fprintf(stderr, "nxagentSendDeferredBackgroundExposures: Going to send deferred exposures to the root window.\n"); #endif - TraverseTree(WindowTable[0], nxagentClipAndSendClearExpose, (void *) nxagentDeferredBackgroundExposures); + TraverseTree(screenInfo.screens[0]->root, nxagentClipAndSendClearExpose, (void *) nxagentDeferredBackgroundExposures); RegionEmpty(nxagentDeferredBackgroundExposures); } diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c index 0a6540fa3..52b869f71 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Events.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c @@ -629,8 +629,8 @@ void nxagentShadowSwitchResizeMode(ScreenPtr pScreen) { nxagentShadowSetRatio(1.0, 1.0); - nxagentShadowCreateMainWindow(screenInfo.screens[DefaultScreen(nxagentDisplay)], WindowTable[0], - WindowTable[0] -> drawable.width, WindowTable[0] -> drawable.height); + nxagentShadowCreateMainWindow(screenInfo.screens[DefaultScreen(nxagentDisplay)], screenInfo.screens[0]->root, + screenInfo.screens[0]->root -> drawable.width, screenInfo.screens[0]->root -> drawable.height); sizeHints.max_width = nxagentOption(RootWidth); sizeHints.max_height = nxagentOption(RootHeight); @@ -640,13 +640,13 @@ void nxagentShadowSwitchResizeMode(ScreenPtr pScreen) else { nxagentShadowSetRatio(nxagentOption(Width) * 1.0 / - WindowTable[0] -> drawable.width, + screenInfo.screens[0]->root -> drawable.width, nxagentOption(Height) * 1.0 / - WindowTable[0] -> drawable.height); + screenInfo.screens[0]->root -> drawable.height); nxagentShadowCreateMainWindow(screenInfo.screens[DefaultScreen(nxagentDisplay)], - WindowTable[0], WindowTable[0] -> drawable.width, - WindowTable[0] -> drawable.height); + screenInfo.screens[0]->root, screenInfo.screens[0]->root -> drawable.width, + screenInfo.screens[0]->root -> drawable.height); sizeHints.max_width = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)); sizeHints.max_height = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)); @@ -963,10 +963,10 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate) case doDebugTree: { fprintf(stderr, "\n ========== nxagentRemoteWindowsTree ==========\n"); - nxagentRemoteWindowsTree(nxagentWindow(WindowTable[0]), 0); + nxagentRemoteWindowsTree(nxagentWindow(screenInfo.screens[0]->root), 0); fprintf(stderr, "\n========== nxagentInternalWindowsTree ==========\n"); - nxagentInternalWindowsTree(WindowTable[0], 0); + nxagentInternalWindowsTree(screenInfo.screens[0]->root, 0); break; } @@ -1405,7 +1405,7 @@ FIXME: Don't enqueue the KeyRelease event if the key was (X.xmotion.y_root < nxagentLastEnteredTopLevelWindow -> drawable.y + 4)) { if (pWin && nxagentClientIsDialog(wClient(pWin)) == 0 && - nxagentLastEnteredTopLevelWindow -> parent == WindowTable[0] && + nxagentLastEnteredTopLevelWindow -> parent == screenInfo.screens[0]->root && nxagentLastEnteredTopLevelWindow -> overrideRedirect == False && X.xmotion.x_root > (nxagentLastEnteredTopLevelWindow -> drawable.x + (nxagentLastEnteredTopLevelWindow -> drawable.width >> 1) - 50) && @@ -1625,7 +1625,7 @@ FIXME: Don't enqueue the KeyRelease event if the key was if (pWin != NULL) { for (pTLWin = pWin; - pTLWin -> parent != WindowTable[pTLWin -> drawable.pScreen -> myNum]; + pTLWin -> parent != pTLWin -> drawable.pScreen -> root; pTLWin = pTLWin -> parent); } @@ -2454,7 +2454,7 @@ FIXME: This can be maybe optimized by consuming the RegionValidate(&sum, &overlap); RegionIntersect(&sum, &sum, - &WindowTable[pWin->drawable.pScreen->myNum]->winSize); + &pWin->drawable.pScreen->root->winSize); #ifdef DEBUG fprintf(stderr, "nxagentHandleExposeEvent: Sending events for window id [%ld].\n", @@ -3147,7 +3147,7 @@ int nxagentCheckWindowConfiguration(XConfigureEvent* X) fprintf(stderr, "nxagentCheckWindowConfiguration: Before restacking top level window [%p]\n", (void *) nxagentWindowPtr(X -> window)); - for (pSib = WindowTable[0] -> firstChild; pSib; pSib = pSib -> nextSib) + for (pSib = screenInfo.screens[0]->root -> firstChild; pSib; pSib = pSib -> nextSib) { fprintf(stderr, "nxagentCheckWindowConfiguration: Top level window: [%p].\n", (void *) pSib); @@ -3431,7 +3431,7 @@ int nxagentHandleConfigureNotify(XEvent* X) nxagentUpdateViewportFrame(0, 0, nxagentOption(RootWidth), nxagentOption(RootHeight)); - XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]), + XMoveWindow(nxagentDisplay, nxagentWindow(pScreen->root), nxagentOption(RootX), nxagentOption(RootY)); } @@ -4245,7 +4245,7 @@ void nxagentForwardRemoteExpose(void) fprintf(stderr, "nxagentForwardRemoteExpose: Going to forward events.\n"); #endif - TraverseTree(WindowTable[0], nxagentClipAndSendExpose, (void *)nxagentRemoteExposeRegion); + TraverseTree(screenInfo.screens[0]->root, nxagentClipAndSendExpose, (void *)nxagentRemoteExposeRegion); /* * Now this region should be empty. @@ -4420,7 +4420,7 @@ int nxagentHandleRRScreenChangeNotify(XEvent *X) nxagentResizeScreen(screenInfo.screens[DefaultScreen(nxagentDisplay)], Xr -> width, Xr -> height, Xr -> mwidth, Xr -> mheight); - nxagentShadowCreateMainWindow(screenInfo.screens[DefaultScreen(nxagentDisplay)], WindowTable[0], + nxagentShadowCreateMainWindow(screenInfo.screens[DefaultScreen(nxagentDisplay)], screenInfo.screens[0]->root, Xr -> width, Xr -> height); nxagentShadowSetWindowsSize(); diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c index adeaff870..5e89e67bd 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c +++ b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c @@ -344,13 +344,13 @@ InitSelections() CurrentSelections[0].selection = XA_PRIMARY; CurrentSelections[0].lastTimeChanged = ClientTimeToServerTime(0); - CurrentSelections[0].window = WindowTable[0]->drawable.id; + CurrentSelections[0].window = screenInfo.screens[0]->root->drawable.id; CurrentSelections[0].pWin = NULL; CurrentSelections[0].client = NullClient; CurrentSelections[1].selection = MakeAtom("CLIPBOARD", 9, 1); CurrentSelections[1].lastTimeChanged = ClientTimeToServerTime(0); - CurrentSelections[1].window = WindowTable[0]->drawable.id; + CurrentSelections[1].window = screenInfo.screens[0]->root->drawable.id; CurrentSelections[1].pWin = NULL; CurrentSelections[1].client = NullClient; } @@ -374,8 +374,8 @@ FlushClientCaches(XID id) { if (client->lastDrawableID == id) { - client->lastDrawableID = WindowTable[0]->drawable.id; - client->lastDrawable = (DrawablePtr)WindowTable[0]; + client->lastDrawableID = screenInfo.screens[0]->root->drawable.id; + client->lastDrawable = (DrawablePtr)screenInfo.screens[0]->root; } else if (client->lastGCID == id) { @@ -1161,7 +1161,7 @@ GetGeometry(register ClientPtr client, xGetGeometryReply *rep) rep->type = X_Reply; rep->length = 0; rep->sequenceNumber = client->sequence; - rep->root = WindowTable[pDraw->pScreen->myNum]->drawable.id; + rep->root = pDraw->pScreen->root->drawable.id; rep->depth = pDraw->depth; rep->width = pDraw->width; rep->height = pDraw->height; @@ -1221,7 +1221,7 @@ ProcQueryTree(register ClientPtr client) return(BadWindow); memset(&reply, 0, sizeof(xQueryTreeReply)); reply.type = X_Reply; - reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id; + reply.root = pWin->drawable.pScreen->root->drawable.id; reply.sequenceNumber = client->sequence; if (pWin->parent) reply.parent = pWin->parent->drawable.id; @@ -4319,8 +4319,8 @@ void InitClient(ClientPtr client, int i, void * ospriv) if (i) { client->closeDownMode = DestroyAll; - client->lastDrawable = (DrawablePtr)WindowTable[0]; - client->lastDrawableID = WindowTable[0]->drawable.id; + client->lastDrawable = (DrawablePtr)screenInfo.screens[0]->root; + client->lastDrawableID = screenInfo.screens[0]->root->drawable.id; } else { @@ -4563,8 +4563,8 @@ SendConnSetup(register ClientPtr client, char *reason) register unsigned int j; register xDepth *pDepth; - root->currentInputMask = WindowTable[i]->eventMask | - wOtherEventMasks (WindowTable[i]); + root->currentInputMask = screenInfo.screens[i]->root->eventMask | + wOtherEventMasks (screenInfo.screens[i]->root); pDepth = (xDepth *)(root + 1); for (j = 0; j < root->nDepths; j++) { diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c index 89c5c0b19..3142233ac 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c +++ b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c @@ -162,7 +162,6 @@ extern Bool XkbFilterEvents(ClientPtr, int, xEvent *); #endif #ifdef XEVIE -extern WindowPtr *WindowTable; extern int xevieFlag; extern int xevieClientIndex; extern DeviceIntPtr xeviemouse; @@ -465,9 +464,10 @@ XineramaCheckPhysLimits( static Bool XineramaSetWindowPntrs(WindowPtr pWin) { - if(pWin == WindowTable[0]) { - memcpy(sprite.windows, WindowTable, - PanoramiXNumScreens*sizeof(WindowPtr)); + if(pWin == screenInfo.screens[0]->root) { + int i; + for (i = 0; i < PanoramiXNumScreens; i++) + sprite.windows[i] = screenInfo.screens[i]->root; } else { PanoramiXRes *win; int i; @@ -692,7 +692,7 @@ XineramaConfineCursorToWindow(WindowPtr pWin, Bool generateEvents) sprite.hotShape = NullRegion; sprite.confined = FALSE; - sprite.confineWin = (pWin == WindowTable[0]) ? NullWindow : pWin; + sprite.confineWin = (pWin == screenInfo.screens[0]->root) ? NullWindow : pWin; XineramaCheckPhysLimits(sprite.current, generateEvents); } @@ -909,7 +909,7 @@ CheckVirtualMotion( qe->event->u.keyButtonPointer.rootY = sprite.hot.y; } } - ROOT = WindowTable[sprite.hot.pScreen->myNum]; + ROOT = sprite.hot.pScreen->root; } static void @@ -1109,7 +1109,7 @@ EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count) */ if (xE->u.u.type == MotionNotify) XE_KBPTR.root = - WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id; + sprite.hotPhys.pScreen->root->drawable.id; eventinfo.events = xE; eventinfo.count = count; CallCallbacks(&DeviceEventCallback, (void *)&eventinfo); @@ -1272,7 +1272,7 @@ playmore: ConfineCursorToWindow(grab->confineTo, TRUE, TRUE); } else - ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum], + ConfineCursorToWindow(sprite.hotPhys.pScreen->root, TRUE, FALSE); PostNewCursor(); } @@ -1290,7 +1290,7 @@ ScreenRestructured (ScreenPtr pScreen) ConfineCursorToWindow(grab->confineTo, TRUE, TRUE); } else - ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum], + ConfineCursorToWindow(sprite.hotPhys.pScreen->root, TRUE, FALSE); } #endif @@ -2219,7 +2219,7 @@ CheckMotion(xEvent *xE) if (sprite.hot.pScreen != sprite.hotPhys.pScreen) { sprite.hot.pScreen = sprite.hotPhys.pScreen; - ROOT = WindowTable[sprite.hot.pScreen->myNum]; + ROOT = sprite.hot.pScreen->root; } #ifdef XEVIE xeviehot.x = @@ -2307,9 +2307,9 @@ WindowsRestructured() #ifdef PANORAMIX /* This was added to support reconfiguration under Xdmx. The problem is - * that if the 0th screen (i.e., WindowTable[0]) is moved to an origin - * other than 0,0, the information in the private sprite structure must - * be updated accordingly, or XYToWindow (and other routines) will not + * that if the 0th screen (i.e., screenInfo.screens[0]->root) is moved to + * an origin other than 0,0, the information in the private sprite structure + * must be updated accordingly, or XYToWindow (and other routines) will not * compute correctly. */ void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff) { @@ -2339,7 +2339,7 @@ void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff) sprite.hotPhys.x = sprite.hotPhys.y = 0; ConfineCursorToWindow(grab->confineTo, TRUE, TRUE); } else - ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum], + ConfineCursorToWindow(sprite.hotPhys.pScreen->root, TRUE, FALSE); } #endif @@ -2435,7 +2435,7 @@ NewCurrentScreen(ScreenPtr newScreen, int x, int y) if(sprite.confineWin) XineramaConfineCursorToWindow(sprite.confineWin, TRUE); else - XineramaConfineCursorToWindow(WindowTable[0], TRUE); + XineramaConfineCursorToWindow(screenInfo.screens[0]->root, TRUE); /* if the pointer wasn't confined, the DDX won't get told of the pointer warp so we reposition it here */ if(!syncEvents.playingEvents) @@ -2448,7 +2448,7 @@ NewCurrentScreen(ScreenPtr newScreen, int x, int y) } else #endif if (newScreen != sprite.hotPhys.pScreen) - ConfineCursorToWindow(WindowTable[newScreen->myNum], TRUE, FALSE); + ConfineCursorToWindow(newScreen->root, TRUE, FALSE); } #ifdef PANORAMIX @@ -2520,7 +2520,7 @@ XineramaWarpPointer(ClientPtr client) winX = source->drawable.x; winY = source->drawable.y; - if(source == WindowTable[0]) { + if(source == screenInfo.screens[0]->root) { winX -= panoramiXdataPtr[0].x; winY -= panoramiXdataPtr[0].y; } @@ -2536,7 +2536,7 @@ XineramaWarpPointer(ClientPtr client) if (dest) { x = dest->drawable.x; y = dest->drawable.y; - if(dest == WindowTable[0]) { + if(dest == screenInfo.screens[0]->root) { x -= panoramiXdataPtr[0].x; y -= panoramiXdataPtr[0].y; } @@ -3206,7 +3206,7 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count /* see comment in EnqueueEvents regarding the next three lines */ if (xE->u.u.type == MotionNotify) XE_KBPTR.root = - WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id; + sprite.hotPhys.pScreen->root->drawable.id; eventinfo.events = xE; eventinfo.count = count; CallCallbacks(&DeviceEventCallback, (void *)&eventinfo); @@ -3818,11 +3818,11 @@ DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode) /* Notify all the roots */ #ifdef PANORAMIX if ( !noPanoramiXExtension ) - FocusEvent(dev, FocusOut, mode, out, WindowTable[0]); + FocusEvent(dev, FocusOut, mode, out, screenInfo.screens[0]->root); else #endif for (i=0; iroot); } else { @@ -3837,11 +3837,11 @@ DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode) /* Notify all the roots */ #ifdef PANORAMIX if ( !noPanoramiXExtension ) - FocusEvent(dev, FocusIn, mode, in, WindowTable[0]); + FocusEvent(dev, FocusIn, mode, in, screenInfo.screens[0]->root); else #endif for (i=0; iroot); if (toWin == PointerRootWin) (void)FocusInEvents(dev, ROOT, sprite.win, NullWindow, mode, NotifyPointer, TRUE); @@ -3855,11 +3855,11 @@ DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode) TRUE); #ifdef PANORAMIX if ( !noPanoramiXExtension ) - FocusEvent(dev, FocusOut, mode, out, WindowTable[0]); + FocusEvent(dev, FocusOut, mode, out, screenInfo.screens[0]->root); else #endif for (i=0; iroot); if (toWin->parent != NullWindow) (void)FocusInEvents(dev, ROOT, toWin, toWin, mode, NotifyNonlinearVirtual, TRUE); diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c b/nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c index ad75b43f8..a52a5200a 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c +++ b/nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c @@ -504,7 +504,7 @@ miSendExposures(pWin, pRgn, dx, dy) if(!pWin->parent) { x = panoramiXdataPtr[scrnum].x; y = panoramiXdataPtr[scrnum].y; - pWin = WindowTable[0]; + pWin = screenInfo.screens[0]->root; realWin = pWin->drawable.id; } else if (scrnum) { PanoramiXRes *win; @@ -788,7 +788,7 @@ int what; gcmask |= GCFunction | GCClipMask; i = pScreen->myNum; - pRoot = WindowTable[i]; + pRoot = screenInfo.screens[i]->root; pBgWin = pWin; if (what == PW_BORDER) diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c index 1999c33b0..238e5a39c 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c +++ b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c @@ -3204,7 +3204,7 @@ PanoramiXRenderCreatePicture (ClientPtr client) newPict->info[0].id = stuff->pid; if (refDraw->type == XRT_WINDOW && - stuff->drawable == WindowTable[0]->drawable.id) + stuff->drawable == screenInfo.screens[0]->root->drawable.id) { newPict->u.pict.root = TRUE; } diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXresource.c b/nx-X11/programs/Xserver/hw/nxagent/NXresource.c index 39a1992de..226d20f34 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/NXresource.c +++ b/nx-X11/programs/Xserver/hw/nxagent/NXresource.c @@ -699,8 +699,8 @@ FreeResource(XID id, RESTYPE skipDeleteFuncType) } if(clients[cid] && (id == clients[cid]->lastDrawableID)) { - clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0]; - clients[cid]->lastDrawableID = WindowTable[0]->drawable.id; + clients[cid]->lastDrawable = (DrawablePtr)screenInfo.screens[0]->root; + clients[cid]->lastDrawableID = screenInfo.screens[0]->root->drawable.id; } } if (!gotOne) @@ -740,8 +740,8 @@ FreeResourceByType(XID id, RESTYPE type, Bool skipFree) } if(clients[cid] && (id == clients[cid]->lastDrawableID)) { - clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0]; - clients[cid]->lastDrawableID = WindowTable[0]->drawable.id; + clients[cid]->lastDrawable = (DrawablePtr)screenInfo.screens[0]->root; + clients[cid]->lastDrawableID = screenInfo.screens[0]->root->drawable.id; } } } diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c index 70c378b9e..5daa65443 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c +++ b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c @@ -240,7 +240,7 @@ PrintWindowTree() for (i=0; iroot; RegionPrint(&pWin->clipList); p1 = pWin->firstChild; PrintChildren(p1, 4); @@ -286,7 +286,7 @@ TraverseTree(register WindowPtr pWin, VisitWindowProcPtr func, void * data) int WalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, void * data) { - return(TraverseTree(WindowTable[pScreen->myNum], func, data)); + return(TraverseTree(pScreen->root, func, data)); } /* hack for forcing backing store on all windows */ @@ -457,7 +457,9 @@ CreateRootWindow(ScreenPtr pScreen) savedScreenInfo[pScreen->myNum].ExternalScreenSaver = NULL; screenIsSaved = SCREEN_SAVER_OFF; - WindowTable[pScreen->myNum] = pWin; + pScreen->root = pWin; + + pScreen->root = pWin; pWin->drawable.pScreen = pScreen; pWin->drawable.type = DRAWABLE_WINDOW; @@ -583,11 +585,11 @@ InitRootWindow(WindowPtr pWin) /* * A root window is created for each screen by main - * and the pointer is saved in WindowTable as in the - * following snippet: + * and the pointer is saved in screenInfo.screens as + * in the following snippet: * * for (i = 0; i < screenInfo.numScreens; i++) - * InitRootWindow(WindowTable[i]); + * InitRootWindow(screenInfo.screens[i]->root); * * Our root window on the real display was already * created at the time the screen was opened, so it @@ -1583,7 +1585,7 @@ ChangeWindowAttributes(register WindowPtr pWin, Mask vmask, XID *vlist, ClientPt */ if ( cursorID == None) { - if (pWin == WindowTable[pWin->drawable.pScreen->myNum]) + if (pWin == pWin->drawable.pScreen->root) pCursor = rootCursor; else pCursor = (CursorPtr) None; @@ -2863,7 +2865,7 @@ ReparentWindow(register WindowPtr pWin, register WindowPtr pParent, pWin->parent = pParent; pPrev = RealChildHead(pParent); - if (pWin->parent == WindowTable[0]) + if (pWin->parent == screenInfo.screens[0]->root) { nxagentSetTopLevelEventMask(pWin); } @@ -3442,7 +3444,7 @@ HandleSaveSet(register ClientPtr client) pWin = SaveSetWindow(client->saveSet[j]); #ifdef XFIXES if (SaveSetToRoot(client->saveSet[j])) - pParent = WindowTable[pWin->drawable.pScreen->myNum]; + pParent = pWin->drawable.pScreen->root; else #endif { @@ -3744,9 +3746,9 @@ TileScreenSaver(int i, int kind) attri = 0; switch (kind) { case SCREEN_IS_TILED: - switch (WindowTable[i]->backgroundState) { + switch (screenInfo.screens[i]->root->backgroundState) { case BackgroundPixel: - attributes[attri++] = WindowTable[i]->background.pixel; + attributes[attri++] = screenInfo.screens[i]->root->background.pixel; mask |= CWBackPixel; break; case BackgroundPixmap: @@ -3758,7 +3760,7 @@ TileScreenSaver(int i, int kind) } break; case SCREEN_IS_BLACK: - attributes[attri++] = WindowTable[i]->drawable.pScreen->blackPixel; + attributes[attri++] = screenInfo.screens[i]->root->drawable.pScreen->blackPixel; mask |= CWBackPixel; break; } @@ -3806,12 +3808,12 @@ TileScreenSaver(int i, int kind) pWin = savedScreenInfo[i].pWindow = CreateWindow(savedScreenInfo[i].wid, - WindowTable[i], + screenInfo.screens[i]->root, -RANDOM_WIDTH, -RANDOM_WIDTH, (unsigned short)screenInfo.screens[i]->width + RANDOM_WIDTH, (unsigned short)screenInfo.screens[i]->height + RANDOM_WIDTH, 0, InputOutput, mask, attributes, 0, serverClient, - wVisual (WindowTable[i]), &result); + wVisual (screenInfo.screens[i]->root), &result); if (cursor) FreeResource (cursorID, RT_NONE); diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c b/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c index c9f62b1fe..f429f1499 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c @@ -1449,7 +1449,7 @@ Bool nxagentFbOnShadowDisplay() XGCValues value; XImage *image; Visual *pVisual; - WindowPtr pWin = WindowTable[0]; + WindowPtr pWin = screenInfo.screens[0]->root; unsigned int format; int depth, width, height, length; char *data = NULL; diff --git a/nx-X11/programs/Xserver/hw/nxagent/Rootless.c b/nx-X11/programs/Xserver/hw/nxagent/Rootless.c index a725e20e7..49877f9d7 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Rootless.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Rootless.c @@ -20,6 +20,7 @@ #include "../../include/window.h" #include "windowstr.h" #include "colormapst.h" +#include "scrnintstr.h" #include "propertyst.h" #include "Agent.h" @@ -242,7 +243,7 @@ Bool nxagentRootlessTreesMatch() Window *children_return; unsigned int nChildrenReturn; WindowPtr pW; - WindowPtr pTestWin = WindowTable[0] -> firstChild; + WindowPtr pTestWin = screenInfo.screens[0]->root -> firstChild; Bool treesMatch = True; Status result; @@ -267,7 +268,7 @@ Bool nxagentRootlessTreesMatch() pW = nxagentRootlessTopLevelWindow(children_return[nChildrenReturn]); } - if (pW && pW != WindowTable[0]) + if (pW && pW != screenInfo.screens[0]->root) { if (treesMatch && pTestWin && pTestWin == pW) { @@ -316,7 +317,7 @@ void nxagentRootlessRestack(unsigned long children[], unsigned int nchildren) pWin = nxagentRootlessTopLevelWindow(children[i]); } - if (pWin && pWin != WindowTable[0]) + if (pWin && pWin != screenInfo.screens[0]->root) { toplevel[ntoplevel++] = pWin; } @@ -338,14 +339,14 @@ void nxagentRootlessRestack(unsigned long children[], unsigned int nchildren) fprintf(stderr, "nxagentRootlessRestack: Internal top level windows before restack:"); - for (pWin = WindowTable[0] -> firstChild; pWin != NULL; pWin = pWin -> nextSib) + for (pWin = screenInfo.screens[0]->root -> firstChild; pWin != NULL; pWin = pWin -> nextSib) { fprintf(stderr, "[%p]\n", pWin); } #endif - pWin = WindowTable[0] -> firstChild; + pWin = screenInfo.screens[0]->root -> firstChild; values[1] = (XID) Above; @@ -381,7 +382,7 @@ void nxagentRootlessRestack(unsigned long children[], unsigned int nchildren) fprintf(stderr, "nxagentRootlessRestack: Internal top level windows after restack:"); - for (pWin = WindowTable[0] -> firstChild; pWin != NULL; pWin = pWin -> nextSib) + for (pWin = screenInfo.screens[0]->root -> firstChild; pWin != NULL; pWin = pWin -> nextSib) { fprintf(stderr, "[%p]\n", pWin); } diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index 50d278ed7..a4b39a4fe 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -2116,7 +2116,7 @@ Bool nxagentCloseScreen(int index, ScreenPtr pScreen) static void nxagentSetRootClip (ScreenPtr pScreen, Bool enable) { - WindowPtr pWin = WindowTable[pScreen->myNum]; + WindowPtr pWin = pScreen->root; WindowPtr pChild; Bool WasViewable = (Bool)(pWin->viewable); Bool anyMarked = FALSE; @@ -2409,21 +2409,21 @@ FIXME: We should try to restore the previously box.x2 = width; box.y2 = height; - WindowTable[pScreen -> myNum] -> drawable.width = width; - WindowTable[pScreen -> myNum] -> drawable.height = height; - WindowTable[pScreen -> myNum] -> drawable.x = 0; - WindowTable[pScreen -> myNum] -> drawable.y = 0; + pScreen->root -> drawable.width = width; + pScreen->root -> drawable.height = height; + pScreen->root -> drawable.x = 0; + pScreen->root -> drawable.y = 0; - RegionInit(&WindowTable[pScreen -> myNum] -> borderSize, &box, 1); - RegionInit(&WindowTable[pScreen -> myNum] -> winSize, &box, 1); - RegionInit(&WindowTable[pScreen -> myNum] -> clipList, &box, 1); - RegionInit(&WindowTable[pScreen -> myNum] -> borderClip, &box, 1); + RegionInit(&pScreen->root -> borderSize, &box, 1); + RegionInit(&pScreen->root -> winSize, &box, 1); + RegionInit(&pScreen->root -> clipList, &box, 1); + RegionInit(&pScreen->root -> borderClip, &box, 1); - (*pScreen -> PositionWindow)(WindowTable[pScreen -> myNum], 0, 0); + (*pScreen -> PositionWindow)(pScreen->root, 0, 0); nxagentSetRootClip(pScreen, 1); - XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[0]), + XMoveWindow(nxagentDisplay, nxagentWindow(screenInfo.screens[0]->root), nxagentOption(RootX), nxagentOption(RootY)); nxagentMoveViewport(pScreen, 0, 0); @@ -3522,7 +3522,7 @@ FIXME: The port information is not used at the moment and produces a { mcop_local_atom = MakeAtom(mcop_atom, strlen(mcop_atom), 1); - ChangeWindowProperty(WindowTable[pScreen->myNum], + ChangeWindowProperty(pScreen->root, mcop_local_atom, XA_STRING, iReturnFormat, PropModeReplace, @@ -3667,9 +3667,9 @@ int nxagentChangeScreenConfig(int screen, int width, int height, int mmWidth, in int r; #ifdef TEST - fprintf(stderr, "nxagentChangeScreenConfig: WindowTable[%d] is %p\n", screen, WindowTable[screen]); + fprintf(stderr, "nxagentChangeScreenConfig: screenInfo.screens[%d]->root is %p\n", screen, screenInfo.screens[screen]); #endif - if (WindowTable[screen] == NULL) + if (screenInfo.screens[screen]->root == NULL) { return 0; } @@ -3692,7 +3692,7 @@ int nxagentChangeScreenConfig(int screen, int width, int height, int mmWidth, in return 0; } - pScreen = WindowTable[screen] -> drawable.pScreen; + pScreen = screenInfo.screens[screen] -> root -> drawable.pScreen; #ifdef TEST fprintf(stderr, "nxagentChangeScreenConfig: Changing config to %dx%d.\n", width, height); @@ -4124,7 +4124,7 @@ void nxagentSaveAreas(PixmapPtr pPixmap, RegionPtr prgnSave, int xorg, int yorg, values.subwindow_mode = IncludeInferiors; - gc = XCreateGC(nxagentDisplay, nxagentWindow(WindowTable[0]), GCSubwindowMode, &values); + gc = XCreateGC(nxagentDisplay, nxagentWindow(screenInfo.screens[0]->root), GCSubwindowMode, &values); /* * Initialize to the corrupted region. @@ -4234,7 +4234,7 @@ void nxagentRestoreAreas(PixmapPtr pPixmap, RegionPtr prgnRestore, int xorg, */ RegionIntersect(prgnRestore, prgnRestore, - &WindowTable[pWin -> drawable.pScreen -> myNum] -> winSize); + &pWin -> drawable.pScreen -> root -> winSize); pBackingStore = (miBSWindowPtr) pWin -> backStorage; @@ -4245,7 +4245,7 @@ void nxagentRestoreAreas(PixmapPtr pPixmap, RegionPtr prgnRestore, int xorg, values.subwindow_mode = ClipByChildren; - gc = XCreateGC(nxagentDisplay, nxagentWindow(WindowTable[0]), GCSubwindowMode, &values); + gc = XCreateGC(nxagentDisplay, nxagentWindow(screenInfo.screens[0]->root), GCSubwindowMode, &values); /* * Translate the reference point to the origin of the window. @@ -4406,7 +4406,7 @@ void nxagentShadowAdaptToRatio(void) nxagentShadowSetRatio(nxagentOption(Width) * 1.0 / nxagentShadowWidth, nxagentOption(Height) * 1.0 / nxagentShadowHeight); - nxagentShadowCreateMainWindow(pScreen, WindowTable[0], nxagentShadowWidth, nxagentShadowHeight); + nxagentShadowCreateMainWindow(pScreen, screenInfo.screens[0]->root, nxagentShadowWidth, nxagentShadowHeight); sizeHints.max_width = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)); sizeHints.max_height = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)); @@ -4456,7 +4456,7 @@ void nxagentShowPixmap(PixmapPtr pPixmap, int x, int y, int width, int height) XlibGC gc; XGCValues value; XImage *image; - WindowPtr pWin = WindowTable[0]; + WindowPtr pWin = screenInfo.screens[0]->root; unsigned int format; int depth, pixmapWidth, pixmapHeight, length; char *data; @@ -4668,7 +4668,7 @@ FIXME value.fill_style = FillSolid; value.function = GXcopy; - gc = XCreateGC(shadow, nxagentWindow(WindowTable[0]), GCBackground | + gc = XCreateGC(shadow, nxagentWindow(screenInfo.screens[0]->root), GCBackground | GCForeground | GCFillStyle | GCPlaneMask | GCFunction, &value); NXCleanImage(image); diff --git a/nx-X11/programs/Xserver/hw/nxagent/Splash.c b/nx-X11/programs/Xserver/hw/nxagent/Splash.c index a069b3e23..35cb7cea9 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Splash.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Splash.c @@ -396,15 +396,15 @@ void nxagentRemoveSplashWindow(WindowPtr pWin) XDestroyWindow(nxagentDisplay, nxagentSplashWindow); nxagentSplashWindow = None; - nxagentRefreshWindows(WindowTable[0]); + nxagentRefreshWindows(screenInfo.screens[0]->root); #ifdef TEST fprintf(stderr, "nxagentRemoveSplashWindow: setting the ownership of %s (%d) on window 0x%lx\n", - "NX_CUT_BUFFER_SERVER", (int)serverCutProperty, nxagentWindow(WindowTable[0])); + "NX_CUT_BUFFER_SERVER", (int)serverCutProperty, nxagentWindow(screenInfo.screens[0]->root)); #endif XSetSelectionOwner(nxagentDisplay, serverCutProperty, - nxagentWindow(WindowTable[0]), CurrentTime); + nxagentWindow(screenInfo.screens[0]->root), CurrentTime); } if (nxagentPixmapLogo) diff --git a/nx-X11/programs/Xserver/hw/nxagent/Window.c b/nx-X11/programs/Xserver/hw/nxagent/Window.c index b553627dd..514ee5140 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Window.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Window.c @@ -196,7 +196,7 @@ static Bool nxagentCheckWindowIntegrity(WindowPtr pWin); WindowPtr nxagentGetWindowFromID(Window id) { - WindowPtr pWin = WindowTable[0]; + WindowPtr pWin = screenInfo.screens[0]->root; while (pWin && nxagentWindowPriv(pWin)) { @@ -508,7 +508,7 @@ FIXME: Do all the windows for which nxagentWindowTopLevel(pWin) Bool nxagentSomeWindowsAreMapped() { - WindowPtr pWin = WindowTable[0] -> firstChild; + WindowPtr pWin = screenInfo.screens[0]->root -> firstChild; while (pWin) { @@ -884,7 +884,7 @@ void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn) nxagentUpdateViewportFrame(0, 0, nxagentOption(RootWidth), nxagentOption(RootHeight)); - XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]), + XMoveWindow(nxagentDisplay, nxagentWindow(pScreen->root), nxagentOption(RootX), nxagentOption(RootY)); /* @@ -995,7 +995,7 @@ void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn) nxagentUpdateViewportFrame(0, 0, nxagentOption(Width), nxagentOption(Height)); - XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]), 0, 0); + XMoveWindow(nxagentDisplay, nxagentWindow(pScreen->root), 0, 0); XMapWindow(nxagentDisplay, w); nxagentChangeOption(RootX, 0); @@ -1156,11 +1156,11 @@ void nxagentMoveViewport(ScreenPtr pScreen, int hShift, int vShift) -nxagentOption(RootY) + nxagentOption(Height)); fprintf(stderr, "nxagentMoveViewport: Root geometry x=[%d] y=[%d]\n", - WindowTable[pScreen -> myNum] -> drawable.x, - WindowTable[pScreen -> myNum] -> drawable.y ); + pScreen->root -> drawable.x, + pScreen->root -> drawable.y ); #endif - XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]), + XMoveWindow(nxagentDisplay, nxagentWindow(pScreen->root), nxagentOption(RootX), nxagentOption(RootY)); if (nxagentOption(ClientOs) == ClientOsWinnt) @@ -2437,7 +2437,7 @@ static int nxagentForceExposure(WindowPtr pWin, void * ptr) { RegionPtr exposedRgn; BoxRec Box; - WindowPtr pRoot = WindowTable[pWin->drawable.pScreen->myNum]; + WindowPtr pRoot = pWin->drawable.pScreen->root; if (pWin -> drawable.class != InputOnly) { @@ -2491,7 +2491,7 @@ void nxagentMapDefaultWindows() for (i = 0; i < screenInfo.numScreens; i++) { - WindowPtr pWin = WindowTable[i]; + WindowPtr pWin = screenInfo.screens[i]->root; ScreenPtr pScreen = pWin -> drawable.pScreen; @@ -2606,7 +2606,7 @@ Bool nxagentDisconnectAllWindows(void) for (i = 0; i < screenInfo.numScreens; i++) { - pWin = WindowTable[i]; + pWin = screenInfo.screens[i]->root; nxagentTraverseWindow( pWin, nxagentDisconnectWindow, &succeded); nxagentDefaultWindows[i] = None; } @@ -2684,16 +2684,16 @@ Bool nxagentReconnectAllWindows(void *p0) fprintf(stderr, "nxagentReconnectAllWindows\n"); #endif - if (WindowTable[0] -> backgroundState == BackgroundPixmap && - WindowTable[0] -> background.pixmap == NULL) + if (screenInfo.screens[0]->root -> backgroundState == BackgroundPixmap && + screenInfo.screens[0]->root -> background.pixmap == NULL) { FatalError("nxagentReconnectAllWindows: correct the FIXME\n"); } if (nxagentOption(Fullscreen)) { - WindowTable[0] -> origin.x = nxagentOption(RootX); - WindowTable[0] -> origin.y = nxagentOption(RootY); + screenInfo.screens[0]->root -> origin.x = nxagentOption(RootX); + screenInfo.screens[0]->root -> origin.y = nxagentOption(RootY); } if (!nxagentLoopOverWindows(nxagentReconnectWindow)) @@ -2739,8 +2739,8 @@ Bool nxagentReconnectAllWindows(void *p0) if (nxagentOption(Fullscreen)) { - WindowTable[0] -> origin.x = 0; - WindowTable[0] -> origin.y = 0; + screenInfo.screens[0]->root -> origin.x = 0; + screenInfo.screens[0]->root -> origin.y = 0; } #ifdef NXAGENT_RECONNECT_WINDOW_DEBUG @@ -2751,7 +2751,7 @@ Bool nxagentReconnectAllWindows(void *p0) #endif - if (nxagentInitClipboard(WindowTable[0]) == -1) + if (nxagentInitClipboard(screenInfo.screens[0]->root) == -1) { #ifdef WARNING fprintf(stderr, "nxagentReconnectAllWindows: WARNING! Couldn't initialize the clipboard.\n"); @@ -2848,7 +2848,7 @@ static Bool nxagentLoopOverWindows(void (*pF)(void *, XID, void *)) for (i = 0; i < screenInfo.numScreens; i++) { - pWin = WindowTable[i]; + pWin = screenInfo.screens[i]->root; nxagentTraverseWindow(pWin, pF, &windowSuccess); } @@ -2995,7 +2995,7 @@ FIXME: Do we need to set save unders attribute here? * if a client handles this. */ - if (nxagentOption(Rootless) && (pWin != WindowTable[0])) + if (nxagentOption(Rootless) && (pWin != screenInfo.screens[0]->root)) { if (nxagentWindowTopLevel(pWin)) { @@ -3196,7 +3196,7 @@ static void nxagentReconfigureWindow(void * param0, XID param1, void * data_buff nxagentShapeWindow(pWin); #endif - if (pWin != WindowTable[0]) + if (pWin != screenInfo.screens[0]->root) { if (pWin->realized) { @@ -3238,7 +3238,7 @@ Bool nxagentCheckIllegalRootMonitoring(WindowPtr pWin, Mask mask) Mask invalidMask = SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask; if (nxagentOption(Rootless) && - pWin == WindowTable[0] && + pWin == screenInfo.screens[0]->root && (mask & invalidMask)) { return True; diff --git a/nx-X11/programs/Xserver/hw/nxagent/Windows.h b/nx-X11/programs/Xserver/hw/nxagent/Windows.h index 3ca74ba8e..dedb60299 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Windows.h +++ b/nx-X11/programs/Xserver/hw/nxagent/Windows.h @@ -167,7 +167,7 @@ extern int nxagentWindowPrivateIndex; #define nxagentRefreshScreen() \ do\ {\ - nxagentRefreshWindows(WindowTable[0]);\ + nxagentRefreshWindows(screenInfo.screens[0]->root);\ } while (0) WindowPtr nxagentWindowPtr(Window window); diff --git a/nx-X11/programs/Xserver/include/globals.h b/nx-X11/programs/Xserver/include/globals.h index 5513b82d0..a8b3a62f6 100644 --- a/nx-X11/programs/Xserver/include/globals.h +++ b/nx-X11/programs/Xserver/include/globals.h @@ -20,7 +20,6 @@ extern Bool loadableFonts; extern int defaultColorVisualClass; extern Bool Must_have_memory; -extern WindowPtr *WindowTable; extern int GrabInProgress; extern char *ConnectionInfo; extern Bool noTestExtensions; diff --git a/nx-X11/programs/Xserver/include/scrnintstr.h b/nx-X11/programs/Xserver/include/scrnintstr.h index 2597d6b67..728b16f91 100644 --- a/nx-X11/programs/Xserver/include/scrnintstr.h +++ b/nx-X11/programs/Xserver/include/scrnintstr.h @@ -549,6 +549,7 @@ typedef struct _Screen { void * devPrivate; short numVisuals; VisualPtr visuals; + WindowPtr root; int WindowPrivateLen; unsigned *WindowPrivateSizes; unsigned totalWindowSize; diff --git a/nx-X11/programs/Xserver/mi/mibank.c b/nx-X11/programs/Xserver/mi/mibank.c index 24e202094..b607af1c1 100644 --- a/nx-X11/programs/Xserver/mi/mibank.c +++ b/nx-X11/programs/Xserver/mi/mibank.c @@ -1768,7 +1768,7 @@ miBankGetImage( pBankImage); (*pScreenPriv->pBankGC->ops->CopyArea)( - (DrawablePtr)WindowTable[pScreen->myNum], + (DrawablePtr)pScreen->root, (DrawablePtr)pScreenPriv->pBankPixmap, pScreenPriv->pBankGC, sx + pDrawable->x, sy + pDrawable->y, w, h, 0, 0); @@ -1835,7 +1835,7 @@ miBankGetSpans( continue; (*pScreenPriv->pBankGC->ops->CopyArea)( - (DrawablePtr)WindowTable[pScreen->myNum], + (DrawablePtr)pScreen->root, (DrawablePtr)pScreenPriv->pBankPixmap, pScreenPriv->pBankGC, ppt->x, ppt->y, *pwidth, 1, 0, 0); @@ -1958,7 +1958,7 @@ miBankCopyWindow( ScreenPtr pScreen = pWindow->drawable.pScreen; GCPtr pGC; int dx, dy, nBox; - DrawablePtr pDrawable = (DrawablePtr)WindowTable[pScreen->myNum]; + DrawablePtr pDrawable = (DrawablePtr)pScreen->root; RegionPtr pRgnDst; BoxPtr pBox, pBoxTmp, pBoxNext, pBoxBase, pBoxNew1, pBoxNew2; XID subWindowMode = IncludeInferiors; diff --git a/nx-X11/programs/Xserver/mi/midispcur.c b/nx-X11/programs/Xserver/mi/midispcur.c index a16c2977e..6ffb9efea 100644 --- a/nx-X11/programs/Xserver/mi/midispcur.c +++ b/nx-X11/programs/Xserver/mi/midispcur.c @@ -477,7 +477,7 @@ miDCPutUpCursor (pScreen, pCursor, x, y, source, mask) return FALSE; } pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr; - pWin = WindowTable[pScreen->myNum]; + pWin = pScreen->root; #ifdef ARGB_CURSOR if (pPriv->pPicture) { @@ -523,7 +523,7 @@ miDCSaveUnderCursor (pScreen, x, y, w, h) pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr; pSave = pScreenPriv->pSave; - pWin = WindowTable[pScreen->myNum]; + pWin = pScreen->root; if (!pSave || pSave->drawable.width < w || pSave->drawable.height < h) { if (pSave) @@ -555,7 +555,7 @@ miDCRestoreUnderCursor (pScreen, x, y, w, h) pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr; pSave = pScreenPriv->pSave; - pWin = WindowTable[pScreen->myNum]; + pWin = pScreen->root; if (!pSave) return FALSE; if (!EnsureGC(pScreenPriv->pRestoreGC, pWin)) @@ -581,7 +581,7 @@ miDCChangeSave (pScreen, x, y, w, h, dx, dy) pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr; pSave = pScreenPriv->pSave; - pWin = WindowTable[pScreen->myNum]; + pWin = pScreen->root; /* * restore the bits which are about to get trashed */ @@ -723,7 +723,7 @@ miDCMoveCursor (pScreen, pCursor, x, y, w, h, dx, dy, source, mask) return FALSE; } pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr; - pWin = WindowTable[pScreen->myNum]; + pWin = pScreen->root; pTemp = pScreenPriv->pTemp; if (!pTemp || pTemp->drawable.width != pScreenPriv->pSave->drawable.width || diff --git a/nx-X11/programs/Xserver/mi/miexpose.c b/nx-X11/programs/Xserver/mi/miexpose.c index 379dd380f..7b7480a91 100644 --- a/nx-X11/programs/Xserver/mi/miexpose.c +++ b/nx-X11/programs/Xserver/mi/miexpose.c @@ -468,7 +468,7 @@ miSendExposures(pWin, pRgn, dx, dy) if(!pWin->parent) { x = panoramiXdataPtr[scrnum].x; y = panoramiXdataPtr[scrnum].y; - pWin = WindowTable[0]; + pWin = screenInfo.screens[0]->root; realWin = pWin->drawable.id; } else if (scrnum) { PanoramiXRes *win; @@ -715,7 +715,7 @@ int what; gcmask |= GCFunction | GCClipMask; i = pScreen->myNum; - pRoot = WindowTable[i]; + pRoot = screenInfo.screens[i]->root; pBgWin = pWin; if (what == PW_BORDER) diff --git a/nx-X11/programs/Xserver/mi/mioverlay.c b/nx-X11/programs/Xserver/mi/mioverlay.c index 96d5cc4f0..e89ce8fa0 100644 --- a/nx-X11/programs/Xserver/mi/mioverlay.c +++ b/nx-X11/programs/Xserver/mi/mioverlay.c @@ -317,7 +317,7 @@ miOverlayReparentWindow(WindowPtr pWin, WindowPtr pPriorParent) { if(IN_UNDERLAY(pWin) || HasUnderlayChildren(pWin)) { /* This could probably be more optimal */ - RebuildTree(WindowTable[pWin->drawable.pScreen->myNum]->firstChild); + RebuildTree(pWin->drawable.pScreen->root->firstChild); } } @@ -1733,7 +1733,7 @@ miOverlayChangeBorderWidth( void miOverlaySetRootClip(ScreenPtr pScreen, Bool enable) { - WindowPtr pRoot = WindowTable[pScreen->myNum]; + WindowPtr pRoot = pScreen->root; miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pRoot); MARK_UNDERLAY(pRoot); diff --git a/nx-X11/programs/Xserver/render/render.c b/nx-X11/programs/Xserver/render/render.c index 2dedbc9c4..b165cf549 100644 --- a/nx-X11/programs/Xserver/render/render.c +++ b/nx-X11/programs/Xserver/render/render.c @@ -2663,7 +2663,7 @@ PanoramiXRenderCreatePicture (ClientPtr client) newPict->info[0].id = stuff->pid; if (refDraw->type == XRT_WINDOW && - stuff->drawable == WindowTable[0]->drawable.id) + stuff->drawable == screenInfo.screens[0]->root->drawable.id) { newPict->u.pict.root = TRUE; } diff --git a/nx-X11/programs/Xserver/xfixes/cursor.c b/nx-X11/programs/Xserver/xfixes/cursor.c index 8bdaca84d..acdd9cf2e 100755 --- a/nx-X11/programs/Xserver/xfixes/cursor.c +++ b/nx-X11/programs/Xserver/xfixes/cursor.c @@ -616,7 +616,7 @@ ReplaceCursor (CursorPtr pCursor, } } /* this "knows" that WindowHasNewCursor doesn't depend on it's argument */ - WindowHasNewCursor (WindowTable[0]); + WindowHasNewCursor (screenInfo.screens[0]->root); } static Bool diff --git a/nx-X11/programs/Xserver/xkb/xkbInit.c b/nx-X11/programs/Xserver/xkb/xkbInit.c index 9afe0dacc..bd65c4d97 100644 --- a/nx-X11/programs/Xserver/xkb/xkbInit.c +++ b/nx-X11/programs/Xserver/xkb/xkbInit.c @@ -49,6 +49,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "inputstr.h" #include "opaque.h" #include "property.h" +#include "scrnintstr.h" #define XKBSRV_NEED_FILE_FUNCS #include #include @@ -230,7 +231,7 @@ char * pval; ErrorF("Internal Error! bad size (%d!=%d) for _XKB_RULES_NAMES\n", out,len); } - ChangeWindowProperty(WindowTable[0],name,XA_STRING,8,PropModeReplace, + ChangeWindowProperty(screenInfo.screens[0]->root,name,XA_STRING,8,PropModeReplace, len,pval,True); DEALLOCATE_LOCAL(pval); return True; -- cgit v1.2.3 From 8c7d7bed969e556aa038aa2d45c7c9697dda9de9 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Mon, 20 Jun 2016 16:51:59 +0200 Subject: hw/nxagent/NXresource.c: remove caching of drawables and graphics contexts. The security checks simply bypass the cached values so they are unused. Required code de-duplication in nxagent. (Will be fixed by ArcticaProject/nx-libs#120 later on). --- nx-X11/programs/Xserver/hw/nxagent/NXresource.c | 20 -------------------- 1 file changed, 20 deletions(-) (limited to 'nx-X11/programs/Xserver/hw') diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXresource.c b/nx-X11/programs/Xserver/hw/nxagent/NXresource.c index 226d20f34..96bbde00c 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/NXresource.c +++ b/nx-X11/programs/Xserver/hw/nxagent/NXresource.c @@ -685,8 +685,6 @@ FreeResource(XID id, RESTYPE skipDeleteFuncType) #ifdef NXAGENT_SERVER nxagentResChangedFlag = 1; #endif - if (rtype & RC_CACHED) - FlushClientCaches(res->id); if (rtype != skipDeleteFuncType) (*DeleteFuncs[rtype & TypeMask])(res->value, res->id); xfree(res); @@ -697,11 +695,6 @@ FreeResource(XID id, RESTYPE skipDeleteFuncType) else prev = &res->next; } - if(clients[cid] && (id == clients[cid]->lastDrawableID)) - { - clients[cid]->lastDrawable = (DrawablePtr)screenInfo.screens[0]->root; - clients[cid]->lastDrawableID = screenInfo.screens[0]->root->drawable.id; - } } if (!gotOne) ErrorF("Freeing resource id=%lX which isn't there.\n", @@ -728,8 +721,6 @@ FreeResourceByType(XID id, RESTYPE type, Bool skipFree) #ifdef NXAGENT_SERVER nxagentResChangedFlag = 1; #endif - if (type & RC_CACHED) - FlushClientCaches(res->id); if (!skipFree) (*DeleteFuncs[type & TypeMask])(res->value, res->id); xfree(res); @@ -738,11 +729,6 @@ FreeResourceByType(XID id, RESTYPE type, Bool skipFree) else prev = &res->next; } - if(clients[cid] && (id == clients[cid]->lastDrawableID)) - { - clients[cid]->lastDrawable = (DrawablePtr)screenInfo.screens[0]->root; - clients[cid]->lastDrawableID = screenInfo.screens[0]->root->drawable.id; - } } } @@ -765,8 +751,6 @@ ChangeResourceValue (XID id, RESTYPE rtype, void * value) for (; res; res = res->next) if ((res->id == id) && (res->type == rtype)) { - if (rtype & RC_CACHED) - FlushClientCaches(res->id); res->value = value; return TRUE; } @@ -1027,8 +1011,6 @@ FreeClientNeverRetainResources(ClientPtr client) if (rtype & RC_NEVERRETAIN) { *prev = this->next; - if (rtype & RC_CACHED) - FlushClientCaches(this->id); (*DeleteFuncs[rtype & TypeMask])(this->value, this->id); xfree(this); } @@ -1073,8 +1055,6 @@ FreeClientResources(ClientPtr client) { RESTYPE rtype = this->type; *head = this->next; - if (rtype & RC_CACHED) - FlushClientCaches(this->id); (*DeleteFuncs[rtype & TypeMask])(this->value, this->id); xfree(this); } -- cgit v1.2.3 From 21c3d20fb3e425206b0af228e9ebca6d0566afa4 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Mon, 20 Jun 2016 13:19:08 +0200 Subject: [render] Split out filter finding from filter setting. Backported from X.org: commit acda790e430b2a18c7c35379f6e538f3d01ff221 Author: Keith Packard Date: Fri Mar 14 13:46:30 2008 -0700 [render] Split out filter finding from filter setting. To prepare for RandR using filters in transforms, split out code paths so that the RandR code can validate the filter name and parameters during the transform set operation so that use of the filter later will not have unreportable errors. Backport to nx-libs: Mike Gabriel --- nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h | 7 +++- nx-X11/programs/Xserver/render/filter.c | 51 +++++++++++++++++------ nx-X11/programs/Xserver/render/picturestr.h | 13 ++++-- 3 files changed, 54 insertions(+), 17 deletions(-) (limited to 'nx-X11/programs/Xserver/hw') diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h index b1e56ad25..75e051ce1 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h +++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h @@ -482,7 +482,12 @@ PictFilterPtr PictureFindFilter (ScreenPtr pScreen, char *name, int len); int -SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int nparams); +SetPicturePictFilter (PicturePtr pPicture, PictFilterPtr pFilter, + xFixed *params, int nparams); + +int +SetPictureFilter (PicturePtr pPicture, char *name, int len, + xFixed *params, int nparams); Bool PictureFinishInit (void); diff --git a/nx-X11/programs/Xserver/render/filter.c b/nx-X11/programs/Xserver/render/filter.c index 776bd4237..57a21a8c0 100644 --- a/nx-X11/programs/Xserver/render/filter.c +++ b/nx-X11/programs/Xserver/render/filter.c @@ -215,21 +215,30 @@ PictureFindFilter (ScreenPtr pScreen, char *name, int len) } static Bool -convolutionFilterValidateParams (PicturePtr pPicture, +convolutionFilterValidateParams (ScreenPtr pScreen, int filter, xFixed *params, - int nparams) + int nparams, + int* width, + int* height) { + int w, h; + if (nparams < 3) return FALSE; if (xFixedFrac (params[0]) || xFixedFrac (params[1])) return FALSE; + w = xFixedToInt (params[0]); + h = xFixedToInt (params[1]); + nparams -= 2; - if ((xFixedToInt (params[0]) * xFixedToInt (params[1])) > nparams) + if (w * h > nparams) return FALSE; + *width = w; + *height = h; return TRUE; } @@ -271,10 +280,8 @@ PictureResetFilters (ScreenPtr pScreen) int SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int nparams) { - ScreenPtr pScreen; PictFilterPtr pFilter; - xFixed *new_params; - int i; + ScreenPtr pScreen; if (pPicture->pDrawable) { pScreen = pPicture->pDrawable->pScreen; @@ -288,7 +295,7 @@ SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int if (!pFilter) return BadName; - if (!pPicture->pDrawable) { + if (pPicture->pDrawable == NULL) { int s; /* For source pictures, the picture isn't tied to a screen. So, ensure @@ -303,8 +310,25 @@ SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int } } + return SetPicturePictFilter (pPicture, pFilter, params, nparams); +} + +int +SetPicturePictFilter (PicturePtr pPicture, PictFilterPtr pFilter, + xFixed *params, int nparams) +{ + ScreenPtr pScreen; + int i; + + if (pPicture->pDrawable) + pScreen = pPicture->pDrawable->pScreen; + else + pScreen = screenInfo.screens[0]; + if (pFilter->ValidateParams) { - if (!(*pFilter->ValidateParams) (pPicture, pFilter->id, params, nparams)) + int width, height; + + if (!(*pFilter->ValidateParams) (pScreen, pFilter->id, params, nparams, &width, &height)) return BadMatch; } else if (nparams) { @@ -312,7 +336,7 @@ SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int } if (nparams != pPicture->filter_nparams) { - new_params = xalloc (nparams * sizeof (xFixed)); + xFixed *new_params = xalloc (nparams * sizeof (xFixed)); if (!new_params && nparams) return BadAlloc; @@ -324,9 +348,10 @@ SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int pPicture->filter_params[i] = params[i]; pPicture->filter = pFilter->id; - if (pPicture->pDrawable) { - PictureScreenPtr ps = GetPictureScreen (pScreen); - int result; + if (pPicture->pDrawable) + { + PictureScreenPtr ps = GetPictureScreen(pScreen); + int result; result = (*ps->ChangePictureFilter) (pPicture, pPicture->filter, params, nparams); @@ -335,5 +360,5 @@ SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int } pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT; - return Success; + return ; } diff --git a/nx-X11/programs/Xserver/render/picturestr.h b/nx-X11/programs/Xserver/render/picturestr.h index 96c2b8abc..38d2cc5ec 100644 --- a/nx-X11/programs/Xserver/render/picturestr.h +++ b/nx-X11/programs/Xserver/render/picturestr.h @@ -168,12 +168,14 @@ typedef struct _Picture { SourcePictPtr pSourcePict; } PictureRec; -typedef Bool (*PictFilterValidateParamsProcPtr) (PicturePtr pPicture, int id, - xFixed *params, int nparams); +typedef Bool (*PictFilterValidateParamsProcPtr) (ScreenPtr pScreen, int id, + xFixed *params, int nparams, + int *width, int *height); typedef struct { char *name; int id; PictFilterValidateParamsProcPtr ValidateParams; + int width, height; } PictFilterRec, *PictFilterPtr; #define PictFilterNearest 0 @@ -457,7 +459,12 @@ PictFilterPtr PictureFindFilter (ScreenPtr pScreen, char *name, int len); int -SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int nparams); +SetPicturePictFilter (PicturePtr pPicture, PictFilterPtr pFilter, + xFixed *params, int nparams); + +int +SetPictureFilter (PicturePtr pPicture, char *name, int len, + xFixed *params, int nparams); Bool PictureFinishInit (void); -- cgit v1.2.3 From f9dbc64f0e3c558f9313c3cb87ebee01fe3287cd Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Mon, 20 Jun 2016 15:43:35 +0200 Subject: Move matrix operations from X server to pixman 0.13.2, handle RandR transform matrices in floating point. Backported from X.org, inspired by: commit 9ffc6719390df8fdd0a5295a7a7a0eaea792be45 Author: Keith Packard Date: Mon Nov 24 13:08:48 2008 -0800 Move matrix operations from X server to pixman 0.13.2 pixman 0.13.2 now holds all of the matrix operations. This leaves the protocol conversion routines and some ABI stubs in place Signed-off-by: Keith Packard commit c4b9ab6bf56139fdd8c7c584a6f523c6766cddd6 Author: Keith Packard Date: Tue Apr 29 08:29:42 2008 -0700 Handle transform failure when computing shadow damage area. PictureTransformBounds can fail, when this happens, damage the entire screen so that the shadow gets repainted correctly. commit fa6a1df209bd74da1d545982cca437afc2198cc1 Author: Keith Packard Date: Fri Mar 21 02:35:28 2008 -0700 Avoid overflow in PictureTransformPoint. Fix PictureTransformIsIdentity. PictureTransformPoint computes homogeneous coordinates internally, but fails to handle intermediate values larger than 16.16. Use 64 bit intermediate values while computing the final result at 16.16 and only complain if that result is too large. PictureTransformIsIdentity was completely wrong -- it was not checking for identity transforms at all. commit 49db14e4ac26070ed86088419483888dda18b603 Author: Keith Packard Date: Wed Mar 19 00:46:35 2008 -0700 Handle RandR transform matrices in floating point. RandR matrix computations lose too much precision in fixed point; computations using the inverted matrix can be as much as 10 pixels off. Convert them to double precision values and pass those around. These API changes are fairly heavyweight; the official Render interface remains fixed point, so the fixed point matrix comes along for the ride everywhere. commit 97ab0c6eff870b52c0383b63a78cec49059b2545 Author: Keith Packard Date: Tue Mar 18 15:15:40 2008 -0700 When converting from double to fixed, round carefully. This reduces the matrix representation error after inverting a transformation matrix (although it doesn't eliminate it entirely). Perhaps we should extend Render to include 64-bit floating point transforms... commit 160252d94f04acc95f0a4e0f884ff565a5aa0744 Author: Keith Packard Date: Mon Mar 17 23:03:56 2008 -0700 Add matrix inversion function (uses doubles) The obvious matrix inversion function, coded using doubles to avoid fiddling with fixed point precision adventures. commit ff9d1cd843a9b0aba69a3d788b21d5f6af702590 Author: Keith Packard Date: Thu Mar 13 21:30:18 2008 -0700 Add funcs to convert between protocol and pixman matrices commit f547650328287545a7a4d96df8d6a6c606dd95a9 Author: Keith Packard Date: Thu Mar 13 14:50:13 2008 -0700 Export a bunch of matrix operations from render. The render extension uses many matrix operations internally, this change exposes those functions to other parts of the server, drivers and extensions. The change is motivated by the 'transform' additions to the RandR extension but will likely be useful elsewhere. Backport to nx-libs: Mike Gabriel --- nx-X11/programs/Xserver/hw/nxagent/NXpicture.c | 68 ------------------ nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h | 18 +++++ nx-X11/programs/Xserver/render/Imakefile | 2 + nx-X11/programs/Xserver/render/matrix.c | 86 +++++++++++++++++++++++ nx-X11/programs/Xserver/render/picture.c | 68 ------------------ nx-X11/programs/Xserver/render/picturestr.h | 27 +++++-- 6 files changed, 127 insertions(+), 142 deletions(-) create mode 100644 nx-X11/programs/Xserver/render/matrix.c (limited to 'nx-X11/programs/Xserver/hw') diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c index 5087fa493..10111adec 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c +++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c @@ -2051,74 +2051,6 @@ AddTraps (PicturePtr pPicture, (*ps->AddTraps) (pPicture, xOff, yOff, ntrap, traps); } -#define MAX_FIXED_48_16 ((xFixed_48_16) 0x7fffffff) -#define MIN_FIXED_48_16 (-((xFixed_48_16) 1 << 31)) - -Bool -PictureTransformPoint3d (PictTransformPtr transform, - PictVectorPtr vector) -{ - PictVector result; - int i, j; - xFixed_32_32 partial; - xFixed_48_16 v; - - for (j = 0; j < 3; j++) - { - v = 0; - for (i = 0; i < 3; i++) - { - partial = ((xFixed_48_16) transform->matrix[j][i] * - (xFixed_48_16) vector->vector[i]); - v += partial >> 16; - } - if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16) - return FALSE; - result.vector[j] = (xFixed) v; - } - if (!result.vector[2]) - return FALSE; - *vector = result; - return TRUE; -} - - -Bool -PictureTransformPoint (PictTransformPtr transform, - PictVectorPtr vector) -{ - PictVector result; - int i, j; - xFixed_32_32 partial; - xFixed_48_16 v; - - for (j = 0; j < 3; j++) - { - v = 0; - for (i = 0; i < 3; i++) - { - partial = ((xFixed_48_16) transform->matrix[j][i] * - (xFixed_48_16) vector->vector[i]); - v += partial >> 16; - } - if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16) - return FALSE; - result.vector[j] = (xFixed) v; - } - if (!result.vector[2]) - return FALSE; - for (j = 0; j < 2; j++) - { - partial = (xFixed_48_16) result.vector[j] << 16; - v = partial / result.vector[2]; - if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16) - return FALSE; - vector->vector[j] = (xFixed) v; - } - vector->vector[2] = xFixed1; - return TRUE; -} - #ifndef True # define True 1 #endif diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h index 75e051ce1..68fe80c37 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h +++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h @@ -687,4 +687,22 @@ void PanoramiXRenderInit (void); void PanoramiXRenderReset (void); #endif +/* + * matrix.c + */ + +extern _X_EXPORT void +PictTransform_from_xRenderTransform(PictTransformPtr pict, + xRenderTransform * render); + +extern _X_EXPORT void +xRenderTransform_from_PictTransform(xRenderTransform * render, + PictTransformPtr pict); + +extern _X_EXPORT Bool + PictureTransformPoint(PictTransformPtr transform, PictVectorPtr vector); + +extern _X_EXPORT Bool + PictureTransformPoint3d(PictTransformPtr transform, PictVectorPtr vector); + #endif /* _PICTURESTR_H_ */ diff --git a/nx-X11/programs/Xserver/render/Imakefile b/nx-X11/programs/Xserver/render/Imakefile index 23f9476ea..ff272ecbd 100644 --- a/nx-X11/programs/Xserver/render/Imakefile +++ b/nx-X11/programs/Xserver/render/Imakefile @@ -4,6 +4,7 @@ XCOMM $XFree86: xc/programs/Xserver/render/Imakefile,v 1.10 2002/11/23 02:38:15 SRCS = animcur.c \ filter.c \ glyph.c \ + matrix.c \ miglyph.c \ miindex.c \ mipict.c \ @@ -17,6 +18,7 @@ XCOMM $XFree86: xc/programs/Xserver/render/Imakefile,v 1.10 2002/11/23 02:38:15 OBJS = animcur.o \ filter.o \ glyph.o \ + matrix.o \ miglyph.o \ miindex.o \ mipict.o \ diff --git a/nx-X11/programs/Xserver/render/matrix.c b/nx-X11/programs/Xserver/render/matrix.c new file mode 100644 index 000000000..83cd66c43 --- /dev/null +++ b/nx-X11/programs/Xserver/render/matrix.c @@ -0,0 +1,86 @@ +/* + * Copyright © 2007 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "misc.h" +#include "scrnintstr.h" +#include "os.h" +#include "regionstr.h" +#include "validate.h" +#include "windowstr.h" +#include "input.h" +#include "resource.h" +#include "colormapst.h" +#include "cursorstr.h" +#include "dixstruct.h" +#include "gcstruct.h" +#include "servermd.h" +#include "picturestr.h" + +void +PictTransform_from_xRenderTransform(PictTransformPtr pict, + xRenderTransform * render) +{ + pict->matrix[0][0] = render->matrix11; + pict->matrix[0][1] = render->matrix12; + pict->matrix[0][2] = render->matrix13; + + pict->matrix[1][0] = render->matrix21; + pict->matrix[1][1] = render->matrix22; + pict->matrix[1][2] = render->matrix23; + + pict->matrix[2][0] = render->matrix31; + pict->matrix[2][1] = render->matrix32; + pict->matrix[2][2] = render->matrix33; +} + +void +xRenderTransform_from_PictTransform(xRenderTransform * render, + PictTransformPtr pict) +{ + render->matrix11 = pict->matrix[0][0]; + render->matrix12 = pict->matrix[0][1]; + render->matrix13 = pict->matrix[0][2]; + + render->matrix21 = pict->matrix[1][0]; + render->matrix22 = pict->matrix[1][1]; + render->matrix23 = pict->matrix[1][2]; + + render->matrix31 = pict->matrix[2][0]; + render->matrix32 = pict->matrix[2][1]; + render->matrix33 = pict->matrix[2][2]; +} + +Bool +PictureTransformPoint(PictTransformPtr transform, PictVectorPtr vector) +{ + return pixman_transform_point(transform, vector); +} + +Bool +PictureTransformPoint3d(PictTransformPtr transform, PictVectorPtr vector) +{ + return pixman_transform_point_3d(transform, vector); +} diff --git a/nx-X11/programs/Xserver/render/picture.c b/nx-X11/programs/Xserver/render/picture.c index ddb21a07c..3c43abd67 100644 --- a/nx-X11/programs/Xserver/render/picture.c +++ b/nx-X11/programs/Xserver/render/picture.c @@ -1892,71 +1892,3 @@ AddTraps (PicturePtr pPicture, ValidatePicture (pPicture); (*ps->AddTraps) (pPicture, xOff, yOff, ntrap, traps); } - -#define MAX_FIXED_48_16 ((xFixed_48_16) 0x7fffffff) -#define MIN_FIXED_48_16 (-((xFixed_48_16) 1 << 31)) - -Bool -PictureTransformPoint3d (PictTransformPtr transform, - PictVectorPtr vector) -{ - PictVector result; - int i, j; - xFixed_32_32 partial; - xFixed_48_16 v; - - for (j = 0; j < 3; j++) - { - v = 0; - for (i = 0; i < 3; i++) - { - partial = ((xFixed_48_16) transform->matrix[j][i] * - (xFixed_48_16) vector->vector[i]); - v += partial >> 16; - } - if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16) - return FALSE; - result.vector[j] = (xFixed) v; - } - if (!result.vector[2]) - return FALSE; - *vector = result; - return TRUE; -} - - -Bool -PictureTransformPoint (PictTransformPtr transform, - PictVectorPtr vector) -{ - PictVector result; - int i, j; - xFixed_32_32 partial; - xFixed_48_16 v; - - for (j = 0; j < 3; j++) - { - v = 0; - for (i = 0; i < 3; i++) - { - partial = ((xFixed_48_16) transform->matrix[j][i] * - (xFixed_48_16) vector->vector[i]); - v += partial >> 16; - } - if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16) - return FALSE; - result.vector[j] = (xFixed) v; - } - if (!result.vector[2]) - return FALSE; - for (j = 0; j < 2; j++) - { - partial = (xFixed_48_16) result.vector[j] << 16; - v = partial / result.vector[2]; - if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16) - return FALSE; - vector->vector[j] = (xFixed) v; - } - vector->vector[2] = xFixed1; - return TRUE; -} diff --git a/nx-X11/programs/Xserver/render/picturestr.h b/nx-X11/programs/Xserver/render/picturestr.h index 38d2cc5ec..4969f6cab 100644 --- a/nx-X11/programs/Xserver/render/picturestr.h +++ b/nx-X11/programs/Xserver/render/picturestr.h @@ -54,13 +54,10 @@ typedef struct _PictFormat { IndexFormatRec index; } PictFormatRec; -typedef struct _PictVector { - xFixed vector[3]; -} PictVector, *PictVectorPtr; +typedef struct pixman_vector PictVector, *PictVectorPtr; +typedef struct pixman_transform PictTransform, *PictTransformPtr; -typedef struct _PictTransform { - xFixed matrix[3][3]; -} PictTransform, *PictTransformPtr; +#define pict_f_transform pixman_f_transform #define PICT_GRADIENT_STOPTABLE_SIZE 1024 #define SourcePictTypeSolidFill 0 @@ -664,4 +661,22 @@ void PanoramiXRenderInit (void); void PanoramiXRenderReset (void); #endif +/* + * matrix.c + */ + +extern _X_EXPORT void +PictTransform_from_xRenderTransform(PictTransformPtr pict, + xRenderTransform * render); + +extern _X_EXPORT void +xRenderTransform_from_PictTransform(xRenderTransform * render, + PictTransformPtr pict); + +extern _X_EXPORT Bool + PictureTransformPoint(PictTransformPtr transform, PictVectorPtr vector); + +extern _X_EXPORT Bool + PictureTransformPoint3d(PictTransformPtr transform, PictVectorPtr vector); + #endif /* _PICTURESTR_H_ */ -- cgit v1.2.3 From 36e17bdc6eef7107f4a64d9fa4da005da23df519 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Mon, 20 Jun 2016 15:51:55 +0200 Subject: [render] Split out filter finding from filter setting. Required code de-duplication in nxagent. (Will be fixed by ArcticaProject/nx-libs#120 later on). --- nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'nx-X11/programs/Xserver/hw') diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h index 68fe80c37..74d03f745 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h +++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h @@ -193,12 +193,14 @@ typedef struct _Picture { SourcePictPtr pSourcePict; } PictureRec; -typedef Bool (*PictFilterValidateParamsProcPtr) (PicturePtr pPicture, int id, - xFixed *params, int nparams); +typedef Bool (*PictFilterValidateParamsProcPtr) (ScreenPtr pScreen, int id, + xFixed *params, int nparams, + int *width, int *height); typedef struct { char *name; int id; PictFilterValidateParamsProcPtr ValidateParams; + int width, height; } PictFilterRec, *PictFilterPtr; #define PictFilterNearest 0 -- cgit v1.2.3 From 2e5b98986ffe9de86d7329304ead298c164340bf Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Mon, 20 Jun 2016 15:53:20 +0200 Subject: Move matrix operations from X server to pixman 0.13.2. Required code de-duplication in nxagent. (Will be fixed by ArcticaProject/nx-libs#120 later on). --- nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'nx-X11/programs/Xserver/hw') diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h index 74d03f745..30e1005c2 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h +++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h @@ -78,13 +78,10 @@ typedef struct _PictFormat { IndexFormatRec index; } PictFormatRec; -typedef struct _PictVector { - xFixed vector[3]; -} PictVector, *PictVectorPtr; +typedef struct pixman_vector PictVector, *PictVectorPtr; +typedef struct pixman_transform PictTransform, *PictTransformPtr; -typedef struct _PictTransform { - xFixed matrix[3][3]; -} PictTransform, *PictTransformPtr; +#define pict_f_transform pixman_f_transform #define PICT_GRADIENT_STOPTABLE_SIZE 1024 #define SourcePictTypeSolidFill 0 -- cgit v1.2.3 From c2b1f489d7998c83af73c7cb25bbb2bc53f26094 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Mon, 20 Jun 2016 11:10:06 +0200 Subject: Backport RANDR proto version 1.5 to nx-X11's Xserver. Backported to X.org's /xorg/xserver Git hash level: a6b6e8ba026acedef6336b17adf06aebddd5f22f. --- nx-X11/programs/Xserver/hw/nxagent/Extensions.c | 114 +- nx-X11/programs/Xserver/hw/nxagent/Imakefile | 7 +- nx-X11/programs/Xserver/hw/nxagent/Screen.c | 2 +- nx-X11/programs/Xserver/randr/Imakefile | 21 +- nx-X11/programs/Xserver/randr/randr.c | 325 ++++- nx-X11/programs/Xserver/randr/randr.h | 67 +- nx-X11/programs/Xserver/randr/randrproto.h | 478 ++++++- nx-X11/programs/Xserver/randr/randrstr.h | 673 +++++++--- nx-X11/programs/Xserver/randr/rrcrtc.c | 1298 +++++++++++++++++--- nx-X11/programs/Xserver/randr/rrdispatch.c | 119 +- nx-X11/programs/Xserver/randr/rrinfo.c | 35 +- nx-X11/programs/Xserver/randr/rrmode.c | 106 +- nx-X11/programs/Xserver/randr/rrmonitor.c | 792 ++++++++++++ nx-X11/programs/Xserver/randr/rroutput.c | 308 ++++- nx-X11/programs/Xserver/randr/rrpointer.c | 73 +- nx-X11/programs/Xserver/randr/rrproperty.c | 387 +++--- nx-X11/programs/Xserver/randr/rrprovider.c | 484 ++++++++ nx-X11/programs/Xserver/randr/rrproviderproperty.c | 752 ++++++++++++ nx-X11/programs/Xserver/randr/rrscreen.c | 508 +++++--- nx-X11/programs/Xserver/randr/rrsdispatch.c | 343 +++++- nx-X11/programs/Xserver/randr/rrtransform.c | 301 +++++ nx-X11/programs/Xserver/randr/rrtransform.h | 79 ++ nx-X11/programs/Xserver/randr/rrxinerama.c | 227 ++-- 23 files changed, 6548 insertions(+), 951 deletions(-) create mode 100644 nx-X11/programs/Xserver/randr/rrmonitor.c create mode 100644 nx-X11/programs/Xserver/randr/rrprovider.c create mode 100644 nx-X11/programs/Xserver/randr/rrproviderproperty.c create mode 100644 nx-X11/programs/Xserver/randr/rrtransform.c create mode 100644 nx-X11/programs/Xserver/randr/rrtransform.h (limited to 'nx-X11/programs/Xserver/hw') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Extensions.c b/nx-X11/programs/Xserver/hw/nxagent/Extensions.c index dfa511448..494027927 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Extensions.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Extensions.c @@ -35,6 +35,32 @@ static int nxagentRandRScreenSetSize(ScreenPtr pScreen, CARD16 width, 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, @@ -104,6 +130,29 @@ void nxagentInitRandRExtension(ScreenPtr 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; + pRandRScrPriv -> rrProviderGetProperty; + pRandRScrPriv -> rrProviderSetProperty; + #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; @@ -114,13 +163,70 @@ void nxagentInitRandRExtension(ScreenPtr pScreen) #endif } -void -RRResetProc (ExtensionEntry *extEntry) +#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) { - fprintf(stderr, "RANDR going down - NX version\n"); + /* 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 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 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 /* @@ -137,7 +243,7 @@ nxagentRandRCrtcSet (ScreenPtr pScreen, int numOutputs, RROutputPtr *outputs) { - return RRCrtcNotify(crtc, mode, x, y, rotation, numOutputs, outputs); + return RRCrtcNotify(crtc, mode, x, y, rotation, NULL, numOutputs, outputs); } #endif diff --git a/nx-X11/programs/Xserver/hw/nxagent/Imakefile b/nx-X11/programs/Xserver/hw/nxagent/Imakefile index e9cef5ae3..121a1c774 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Imakefile +++ b/nx-X11/programs/Xserver/hw/nxagent/Imakefile @@ -209,8 +209,11 @@ DEFINES = -g $(OS_DEFINES) $(EXT_DEFINES) $(NX_DEFINES) \ -DNXAGENT_ARTSD \ -DNXAGENT_RANDR_MODE_PREFIX \ -UNX_DEBUG_INPUT \ - -DRANDR_10_INTERFACE \ - -DRANDR_12_INTERFACE \ + -DRANDR_10_INTERFACE=1 \ + -DRANDR_12_INTERFACE=1 \ + -DRANDR_13_INTERFACE=1 \ + -DRANDR_14_INTERFACE=1 \ + -DRANDR_15_INTERFACE=1 \ -DPANORAMIX \ -UDEBUG_TREE diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index a4b39a4fe..40b1e5222 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -3793,7 +3793,7 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) * do this here it will be done implicitely later and add mode(s) to * our crtc(s)! */ - rrgetinfo = RRGetInfo(pScreen); + rrgetinfo = RRGetInfo(pScreen, FALSE); fprintf(stderr, "nxagentAdjustRandRXinerama: RRGetInfo returned [%d]\n", rrgetinfo); } diff --git a/nx-X11/programs/Xserver/randr/Imakefile b/nx-X11/programs/Xserver/randr/Imakefile index 312dfb438..8dc8de1b7 100644 --- a/nx-X11/programs/Xserver/randr/Imakefile +++ b/nx-X11/programs/Xserver/randr/Imakefile @@ -24,11 +24,15 @@ XCOMM $XFree86: xc/programs/Xserver/randr/Imakefile,v 1.1 2001/05/23 03:29:44 ke rrdispatch.c \ rrinfo.c \ rrmode.c \ + rrmonitor.c \ rroutput.c \ rrpointer.c \ rrproperty.c \ + rrprovider.c \ + rrproviderproperty.c \ rrscreen.c \ rrsdispatch.c \ + rrtransform.c \ rrxinerama.c \ $(NULL) @@ -37,11 +41,15 @@ XCOMM $XFree86: xc/programs/Xserver/randr/Imakefile,v 1.1 2001/05/23 03:29:44 ke rrdispatch.o \ rrinfo.o \ rrmode.o \ + rrmonitor.o \ rroutput.o \ rrpointer.o \ rrproperty.o \ + rrprovider.o \ + rrproviderproperty.o \ rrscreen.o \ rrsdispatch.o \ + rrtransform.o \ rrxinerama.o \ $(NULL) @@ -50,9 +58,20 @@ XCOMM $XFree86: xc/programs/Xserver/randr/Imakefile,v 1.1 2001/05/23 03:29:44 ke -I../render \ `pkg-config --cflags-only-I pixman-1` +#if defined(BuildXinerama) + PNRX_DEFINES = -DXINERAMA -DPANORAMIX +#endif + +#if defined(NXAgentServer) + NX_DEFINES = -DNXAGENT_SERVER +#endif + LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln - DEFINES = -DNXAGENT_SERVER + DEFINES = \ + $(PNRX_DEFINES) \ + $(NX_DEFINES) \ + $(NULL) NormalLibraryTarget(randr,$(OBJS)) NormalLibraryObjectRule() diff --git a/nx-X11/programs/Xserver/randr/randr.c b/nx-X11/programs/Xserver/randr/randr.c index 1cb7e5b77..b78a947c8 100644 --- a/nx-X11/programs/Xserver/randr/randr.c +++ b/nx-X11/programs/Xserver/randr/randr.c @@ -50,6 +50,10 @@ #include "randrstr.h" +#ifndef NXAGENT_SERVER +#include "extinit.h" +#endif + /* From render.h */ #ifndef SubPixelUnknown #define SubPixelUnknown 0 @@ -59,12 +63,12 @@ static int RRNScreens; #define wrap(priv,real,mem,func) {\ - priv->mem = real->mem; \ - real->mem = func; \ + ((ScreenPtr)priv)->mem = ((ScreenPtr)real)->mem; \ + ((ScreenPtr)real)->mem = func; \ } #define unwrap(priv,real,mem) {\ - real->mem = priv->mem; \ + ((ScreenPtr)real)->mem = ((ScreenPtr)priv)->mem; \ } static int ProcRRDispatch(ClientPtr pClient); @@ -106,13 +110,12 @@ RRClientCallback(CallbackListPtr *list, void *closure, void *data) } } -static void -RRResetProc(ExtensionEntry * extEntry) -{ -} - static Bool -RRCloseScreen(int i, ScreenPtr pScreen) +RRCloseScreen( +#ifdef NXAGENT_SERVER + int i, +#endif + ScreenPtr pScreen) { rrScrPriv(pScreen); int j; @@ -123,6 +126,11 @@ RRCloseScreen(int i, ScreenPtr pScreen) for (j = pScrPriv->numOutputs - 1; j >= 0; j--) RROutputDestroy(pScrPriv->outputs[j]); + if (pScrPriv->provider) + RRProviderDestroy(pScrPriv->provider); + + RRMonitorClose(pScreen); + xfree(pScrPriv->crtcs); xfree(pScrPriv->outputs); xfree(pScrPriv); @@ -142,11 +150,11 @@ SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent * from, cpswapl(from->root, to->root); cpswapl(from->window, to->window); cpswaps(from->sizeID, to->sizeID); + cpswaps(from->subpixelOrder, to->subpixelOrder); cpswaps(from->widthInPixels, to->widthInPixels); cpswaps(from->heightInPixels, to->heightInPixels); cpswaps(from->widthInMillimeters, to->widthInMillimeters); cpswaps(from->heightInMillimeters, to->heightInMillimeters); - cpswaps(from->subpixelOrder, to->subpixelOrder); } static void @@ -160,8 +168,8 @@ SRRCrtcChangeNotifyEvent(xRRCrtcChangeNotifyEvent * from, cpswapl(from->window, to->window); cpswapl(from->crtc, to->crtc); cpswapl(from->mode, to->mode); - cpswapl(from->window, to->window); cpswaps(from->rotation, to->rotation); + /* pad1 */ cpswaps(from->x, to->x); cpswaps(from->y, to->y); cpswaps(from->width, to->width); @@ -182,6 +190,8 @@ SRROutputChangeNotifyEvent(xRROutputChangeNotifyEvent * from, cpswapl(from->crtc, to->crtc); cpswapl(from->mode, to->mode); cpswaps(from->rotation, to->rotation); + to->connection = from->connection; + to->subpixelOrder = from->subpixelOrder; } static void @@ -195,6 +205,52 @@ SRROutputPropertyNotifyEvent(xRROutputPropertyNotifyEvent * from, cpswapl(from->output, to->output); cpswapl(from->atom, to->atom); cpswapl(from->timestamp, to->timestamp); + to->state = from->state; + /* pad1 */ + /* pad2 */ + /* pad3 */ + /* pad4 */ +} + +static void +SRRProviderChangeNotifyEvent(xRRProviderChangeNotifyEvent * from, + xRRProviderChangeNotifyEvent * to) +{ + to->type = from->type; + to->subCode = from->subCode; + cpswaps(from->sequenceNumber, to->sequenceNumber); + cpswapl(from->timestamp, to->timestamp); + cpswapl(from->window, to->window); + cpswapl(from->provider, to->provider); +} + +static void +SRRProviderPropertyNotifyEvent(xRRProviderPropertyNotifyEvent * from, + xRRProviderPropertyNotifyEvent * to) +{ + to->type = from->type; + to->subCode = from->subCode; + cpswaps(from->sequenceNumber, to->sequenceNumber); + cpswapl(from->window, to->window); + cpswapl(from->provider, to->provider); + cpswapl(from->atom, to->atom); + cpswapl(from->timestamp, to->timestamp); + to->state = from->state; + /* pad1 */ + /* pad2 */ + /* pad3 */ + /* pad4 */ +} + +static void +SRRResourceChangeNotifyEvent(xRRResourceChangeNotifyEvent * from, + xRRResourceChangeNotifyEvent * to) +{ + to->type = from->type; + to->subCode = from->subCode; + cpswaps(from->sequenceNumber, to->sequenceNumber); + cpswapl(from->timestamp, to->timestamp); + cpswapl(from->window, to->window); } static void @@ -213,6 +269,17 @@ SRRNotifyEvent(xEvent *from, xEvent *to) SRROutputPropertyNotifyEvent((xRROutputPropertyNotifyEvent *) from, (xRROutputPropertyNotifyEvent *) to); break; + case RRNotify_ProviderChange: + SRRProviderChangeNotifyEvent((xRRProviderChangeNotifyEvent *) from, + (xRRProviderChangeNotifyEvent *) to); + break; + case RRNotify_ProviderProperty: + SRRProviderPropertyNotifyEvent((xRRProviderPropertyNotifyEvent *) from, + (xRRProviderPropertyNotifyEvent *) to); + break; + case RRNotify_ResourceChange: + SRRResourceChangeNotifyEvent((xRRResourceChangeNotifyEvent *) from, + (xRRResourceChangeNotifyEvent *) to); default: break; } @@ -234,8 +301,15 @@ RRInit(void) return FALSE; if (!RROutputInit()) return FALSE; + if (!RRProviderInit()) + return FALSE; RRGeneration = serverGeneration; } +#ifndef NXAGENT_SERVER + if (!dixRegisterPrivateKey(&rrPrivKeyRec, PRIVATE_SCREEN, 0)) + return FALSE; +#endif /* !defined(NXAGENT_SERVER) */ + return TRUE; } @@ -291,11 +365,15 @@ RRScreenInit(ScreenPtr pScreen) wrap(pScrPriv, pScreen, CloseScreen, RRCloseScreen); + pScreen->ConstrainCursorHarder = RRConstrainCursorHarder; + pScreen->ReplaceScanoutPixmap = RRReplaceScanoutPixmap; pScrPriv->numOutputs = 0; pScrPriv->outputs = NULL; pScrPriv->numCrtcs = 0; pScrPriv->crtcs = NULL; + RRMonitorInit(pScreen); + RRNScreens += 1; /* keep count of screens that implement randr */ return TRUE; } @@ -309,7 +387,13 @@ RRFreeClient(void *data, XID id) pRREvent = (RREventPtr) data; pWin = pRREvent->window; +#ifndef NXAGENT_SERVER + dixLookupResourceByType((void **) &pHead, pWin->drawable.id, + RREventType, serverClient, DixDestroyAccess); +#else /* !defined(NXAGENT_SERVER) */ pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, RREventType); +#endif /* !defined(NXAGENT_SERVER) */ + if (pHead) { pPrev = 0; for (pCur = *pHead; pCur && pCur != pRREvent; pCur = pCur->next) @@ -349,29 +433,38 @@ RRExtensionInit(void) return; #ifndef NXAGENT_SERVER - if (!dixRequestPrivate(RRClientPrivateKey, - sizeof(RRClientRec) + - screenInfo.numScreens * sizeof(RRTimesRec))) + if (!dixRegisterPrivateKey(&RRClientPrivateKeyRec, PRIVATE_CLIENT, + sizeof(RRClientRec) + + screenInfo.numScreens * sizeof(RRTimesRec))) return; -#else +#else /* !defined(NXAGENT_SERVER) */ RRClientPrivateIndex = AllocateClientPrivateIndex(); if (!AllocateClientPrivate(RRClientPrivateIndex, sizeof(RRClientRec) + screenInfo.numScreens * sizeof(RRTimesRec))) return; -#endif +#endif /* !defined(NXAGENT_SERVER) */ + if (!AddCallback(&ClientStateCallback, RRClientCallback, 0)) return; - RRClientType = CreateNewResourceType(RRFreeClient); + RRClientType = CreateNewResourceType(RRFreeClient +#ifndef NXAGENT_SERVER + , "RandRClient" +#endif + ); if (!RRClientType) return; - RREventType = CreateNewResourceType(RRFreeEvents); + RREventType = CreateNewResourceType(RRFreeEvents +#ifndef NXAGENT_SERVER + , "RandREvent" +#endif + ); if (!RREventType) return; extEntry = AddExtension(RANDR_NAME, RRNumberEvents, RRNumberErrors, ProcRRDispatch, SProcRRDispatch, - RRResetProc, StandardMinorOpcode); + NULL, StandardMinorOpcode); if (!extEntry) return; RRErrorBase = extEntry->errorBase; @@ -380,11 +473,45 @@ RRExtensionInit(void) SRRScreenChangeNotifyEvent; EventSwapVector[RREventBase + RRNotify] = (EventSwapPtr) SRRNotifyEvent; + + RRModeInitErrorValue(); + RRCrtcInitErrorValue(); + RROutputInitErrorValue(); + RRProviderInitErrorValue(); #ifdef PANORAMIX RRXineramaExtensionInit(); #endif } +void +RRResourcesChanged(ScreenPtr pScreen) +{ + rrScrPriv(pScreen); + pScrPriv->resourcesChanged = TRUE; + + RRSetChanged(pScreen); +} + +static void +RRDeliverResourceEvent(ClientPtr client, WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + + rrScrPriv(pScreen); + + xRRResourceChangeNotifyEvent re = { + .type = RRNotify + RREventBase, + .subCode = RRNotify_ResourceChange, +#ifdef NXAGENT_SERVER + .sequenceNumber = client->sequence, +#endif + .timestamp = pScrPriv->lastSetTime.milliseconds, + .window = pWin->drawable.id + }; + + WriteEventsToClient(client, 1, (xEvent *) &re); +} + static int TellChanged(WindowPtr pWin, void *value) { @@ -392,10 +519,20 @@ TellChanged(WindowPtr pWin, void *value) ClientPtr client; ScreenPtr pScreen = pWin->drawable.pScreen; +#ifndef NXAGENT_SERVER + ScreenPtr iter; + rrScrPrivPtr pSlaveScrPriv; +#endif + rrScrPriv(pScreen); int i; +#ifndef NXAGENT_SERVER + dixLookupResourceByType((void **) &pHead, pWin->drawable.id, + RREventType, serverClient, DixReadAccess); +#else /* !defined(NXAGENT_SERVER) */ pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, RREventType); +#endif /* !defined(NXAGENT_SERVER) */ if (!pHead) return WT_WALKCHILDREN; @@ -414,6 +551,18 @@ TellChanged(WindowPtr pWin, void *value) if (crtc->changed) RRDeliverCrtcEvent(client, pWin, crtc); } + +#ifndef NXAGENT_SERVER + xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) { + pSlaveScrPriv = rrGetScrPriv(iter); + for (i = 0; i < pSlaveScrPriv->numCrtcs; i++) { + RRCrtcPtr crtc = pSlaveScrPriv->crtcs[i]; + + if (crtc->changed) + RRDeliverCrtcEvent(client, pWin, crtc); + } + } +#endif } if (pRREvent->mask & RROutputChangeNotifyMask) { @@ -423,36 +572,146 @@ TellChanged(WindowPtr pWin, void *value) if (output->changed) RRDeliverOutputEvent(client, pWin, output); } + +#ifndef NXAGENT_SERVER + xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) { + pSlaveScrPriv = rrGetScrPriv(iter); + for (i = 0; i < pSlaveScrPriv->numOutputs; i++) { + RROutputPtr output = pSlaveScrPriv->outputs[i]; + + if (output->changed) + RRDeliverOutputEvent(client, pWin, output); + } + } +#endif + } + +#ifndef NXAGENT_SERVER + if (pRREvent->mask & RRProviderChangeNotifyMask) { + xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) { + pSlaveScrPriv = rrGetScrPriv(iter); + if (pSlaveScrPriv->provider->changed) + RRDeliverProviderEvent(client, pWin, pSlaveScrPriv->provider); + } + xorg_list_for_each_entry(iter, &pScreen->offload_slave_list, offload_head) { + pSlaveScrPriv = rrGetScrPriv(iter); + if (pSlaveScrPriv->provider->changed) + RRDeliverProviderEvent(client, pWin, pSlaveScrPriv->provider); + } + xorg_list_for_each_entry(iter, &pScreen->unattached_list, unattached_head) { + pSlaveScrPriv = rrGetScrPriv(iter); + if (pSlaveScrPriv->provider->changed) + RRDeliverProviderEvent(client, pWin, pSlaveScrPriv->provider); + } + } +#endif + + if (pRREvent->mask & RRResourceChangeNotifyMask) { + if (pScrPriv->resourcesChanged) { + RRDeliverResourceEvent(client, pWin); + } } } return WT_WALKCHILDREN; } +void +RRSetChanged(ScreenPtr pScreen) +{ +#ifndef NXAGENT_SERVER + /* set changed bits on the master screen only */ + ScreenPtr master; + + rrScrPriv(pScreen); + rrScrPrivPtr mastersp; + + if (pScreen->isGPU) { + master = pScreen->current_master; + if (!master) + return; + mastersp = rrGetScrPriv(master); + } + else + { + master = pScreen; + mastersp = pScrPriv; + } + + mastersp->changed = TRUE; +#else /* !defined(NXAGENT_SERVER) */ + rrScrPriv(pScreen); + pScrPriv->changed = TRUE; +#endif +} + /* * Something changed; send events and adjust pointer position */ void RRTellChanged(ScreenPtr pScreen) { + ScreenPtr master; rrScrPriv(pScreen); + rrScrPrivPtr mastersp; int i; +#ifndef NXAGENT_SERVER + ScreenPtr iter; + rrScrPrivPtr pSlaveScrPriv; +#endif - if (pScrPriv->changed) { - UpdateCurrentTime(); - if (pScrPriv->configChanged) { - pScrPriv->lastConfigTime = currentTime; - pScrPriv->configChanged = FALSE; +#ifndef NXAGENT_SERVER + if (pScreen->isGPU) { + master = pScreen->current_master; + mastersp = rrGetScrPriv(master); + } + else +#endif + { + master = pScreen; + mastersp = pScrPriv; + } + + if (mastersp->changed) { + UpdateCurrentTimeIf(); + if (mastersp->configChanged) { + mastersp->lastConfigTime = currentTime; + mastersp->configChanged = FALSE; } pScrPriv->changed = FALSE; - WalkTree(pScreen, TellChanged, (void *) pScreen); + mastersp->changed = FALSE; + + WalkTree(master, TellChanged, (void *) master); + + mastersp->resourcesChanged = FALSE; + for (i = 0; i < pScrPriv->numOutputs; i++) pScrPriv->outputs[i]->changed = FALSE; for (i = 0; i < pScrPriv->numCrtcs; i++) pScrPriv->crtcs[i]->changed = FALSE; - if (pScrPriv->layoutChanged) { + +#ifndef NXAGENT_SERVER + xorg_list_for_each_entry(iter, &master->output_slave_list, output_head) { + pSlaveScrPriv = rrGetScrPriv(iter); + pSlaveScrPriv->provider->changed = FALSE; + for (i = 0; i < pSlaveScrPriv->numOutputs; i++) + pSlaveScrPriv->outputs[i]->changed = FALSE; + for (i = 0; i < pSlaveScrPriv->numCrtcs; i++) + pSlaveScrPriv->crtcs[i]->changed = FALSE; + } + xorg_list_for_each_entry(iter, &master->offload_slave_list, offload_head) { + pSlaveScrPriv = rrGetScrPriv(iter); + pSlaveScrPriv->provider->changed = FALSE; + } + xorg_list_for_each_entry(iter, &master->unattached_list, unattached_head) { + pSlaveScrPriv = rrGetScrPriv(iter); + pSlaveScrPriv->provider->changed = FALSE; + } +#endif /* !defined(NXAGENT_SERVER) */ + + if (mastersp->layoutChanged) { pScrPriv->layoutChanged = FALSE; - RRPointerScreenConfigured(pScreen); - RRSendConfigNotify(pScreen); + RRPointerScreenConfigured(master); + RRSendConfigNotify(master); } } } @@ -468,6 +727,12 @@ RRFirstOutput(ScreenPtr pScreen) RROutputPtr output; int i, j; + if (!pScrPriv) + return NULL; + + if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc) + return pScrPriv->primaryOutput; + for (i = 0; i < pScrPriv->numCrtcs; i++) { RRCrtcPtr crtc = pScrPriv->crtcs[i]; @@ -500,6 +765,7 @@ ProcRRDispatch(ClientPtr client) REQUEST(xReq); if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data]) return BadRequest; + UpdateCurrentTimeIf(); return (*ProcRandrVector[stuff->data]) (client); } @@ -507,7 +773,8 @@ static int SProcRRDispatch(ClientPtr client) { REQUEST(xReq); - if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data]) + if (stuff->data >= RRNumberRequests || !SProcRandrVector[stuff->data]) return BadRequest; + UpdateCurrentTimeIf(); return (*SProcRandrVector[stuff->data]) (client); } diff --git a/nx-X11/programs/Xserver/randr/randr.h b/nx-X11/programs/Xserver/randr/randr.h index a3ef56c77..2018b372e 100644 --- a/nx-X11/programs/Xserver/randr/randr.h +++ b/nx-X11/programs/Xserver/randr/randr.h @@ -2,6 +2,7 @@ * Copyright © 2000 Compaq Computer Corporation * Copyright © 2002 Hewlett Packard Company * Copyright © 2006 Intel Corporation + * Copyright © 2008 Red Hat, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -39,11 +40,11 @@ typedef unsigned long XRandrModeFlags; #define RANDR_NAME "RANDR" #define RANDR_MAJOR 1 -#define RANDR_MINOR 2 +#define RANDR_MINOR 5 -#define RRNumberErrors 3 +#define RRNumberErrors 4 #define RRNumberEvents 2 -#define RRNumberRequests 25 +#define RRNumberRequests 45 #define X_RRQueryVersion 0 /* we skip 1 to make old clients fail pretty immediately */ @@ -77,12 +78,47 @@ typedef unsigned long XRandrModeFlags; #define X_RRGetCrtcGamma 23 #define X_RRSetCrtcGamma 24 +/* V1.3 additions */ +#define X_RRGetScreenResourcesCurrent 25 +#define X_RRSetCrtcTransform 26 +#define X_RRGetCrtcTransform 27 +#define X_RRGetPanning 28 +#define X_RRSetPanning 29 +#define X_RRSetOutputPrimary 30 +#define X_RRGetOutputPrimary 31 + +#define RRTransformUnit (1L << 0) +#define RRTransformScaleUp (1L << 1) +#define RRTransformScaleDown (1L << 2) +#define RRTransformProjective (1L << 3) + +/* v1.4 */ +#define X_RRGetProviders 32 +#define X_RRGetProviderInfo 33 +#define X_RRSetProviderOffloadSink 34 +#define X_RRSetProviderOutputSource 35 +#define X_RRListProviderProperties 36 +#define X_RRQueryProviderProperty 37 +#define X_RRConfigureProviderProperty 38 +#define X_RRChangeProviderProperty 39 +#define X_RRDeleteProviderProperty 40 +#define X_RRGetProviderProperty 41 + +/* v1.5 */ +#define X_RRGetMonitors 42 +#define X_RRSetMonitor 43 +#define X_RRDeleteMonitor 44 + /* Event selection bits */ #define RRScreenChangeNotifyMask (1L << 0) /* V1.2 additions */ #define RRCrtcChangeNotifyMask (1L << 1) #define RROutputChangeNotifyMask (1L << 2) #define RROutputPropertyNotifyMask (1L << 3) +/* V1.4 additions */ +#define RRProviderChangeNotifyMask (1L << 4) +#define RRProviderPropertyNotifyMask (1L << 5) +#define RRResourceChangeNotifyMask (1L << 6) /* Event codes */ #define RRScreenChangeNotify 0 @@ -92,7 +128,9 @@ typedef unsigned long XRandrModeFlags; #define RRNotify_CrtcChange 0 #define RRNotify_OutputChange 1 #define RRNotify_OutputProperty 2 - +#define RRNotify_ProviderChange 3 +#define RRNotify_ProviderProperty 4 +#define RRNotify_ResourceChange 5 /* used in the rotation field; rotation and reflection in 0.1 proto. */ #define RR_Rotate_0 1 #define RR_Rotate_90 2 @@ -133,9 +171,28 @@ typedef unsigned long XRandrModeFlags; #define BadRROutput 0 #define BadRRCrtc 1 #define BadRRMode 2 +#define BadRRProvider 3 /* Conventional RandR output properties */ -#define RR_PROPERTY_RANDR_EDID "RANDR_EDID" +#define RR_PROPERTY_BACKLIGHT "Backlight" +#define RR_PROPERTY_RANDR_EDID "EDID" +#define RR_PROPERTY_SIGNAL_FORMAT "SignalFormat" +#define RR_PROPERTY_SIGNAL_PROPERTIES "SignalProperties" +#define RR_PROPERTY_CONNECTOR_TYPE "ConnectorType" +#define RR_PROPERTY_CONNECTOR_NUMBER "ConnectorNumber" +#define RR_PROPERTY_COMPATIBILITY_LIST "CompatibilityList" +#define RR_PROPERTY_CLONE_LIST "CloneList" +#define RR_PROPERTY_BORDER "Border" +#define RR_PROPERTY_BORDER_DIMENSIONS "BorderDimensions" +#define RR_PROPERTY_GUID "GUID" +#define RR_PROPERTY_RANDR_TILE "TILE" + +/* roles this device can carry out */ +#define RR_Capability_None 0 +#define RR_Capability_SourceOutput 1 +#define RR_Capability_SinkOutput 2 +#define RR_Capability_SourceOffload 4 +#define RR_Capability_SinkOffload 8 #endif /* _RANDR_H_ */ diff --git a/nx-X11/programs/Xserver/randr/randrproto.h b/nx-X11/programs/Xserver/randr/randrproto.h index be5b7adb5..116666ff5 100644 --- a/nx-X11/programs/Xserver/randr/randrproto.h +++ b/nx-X11/programs/Xserver/randr/randrproto.h @@ -2,6 +2,7 @@ * Copyright © 2000 Compaq Computer Corporation * Copyright © 2002 Hewlett-Packard Company * Copyright © 2006 Intel Corporation + * Copyright © 2008 Red Hat, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -30,8 +31,8 @@ #ifndef _XRANDRP_H_ #define _XRANDRP_H_ -/*#include */ #include "randr.h" +#include #define Window CARD32 #define Drawable CARD32 @@ -47,7 +48,9 @@ #define RROutput CARD32 #define RRMode CARD32 #define RRCrtc CARD32 +#define RRProvider CARD32 #define RRModeFlags CARD32 +#define Atom CARD32 #define Rotation CARD16 #define SizeID CARD16 @@ -601,6 +604,296 @@ typedef struct { #define sz_xRRSetCrtcGammaReq 12 +/* + * Additions for V1.3 + */ + +typedef xRRGetScreenResourcesReq xRRGetScreenResourcesCurrentReq; + +#define sz_xRRGetScreenResourcesCurrentReq sz_xRRGetScreenResourcesReq + +typedef xRRGetScreenResourcesReply xRRGetScreenResourcesCurrentReply; + +#define sz_xRRGetScreenResourcesCurrentReply sz_xRRGetScreenResourcesReply + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RRCrtc crtc B32; + xRenderTransform transform; + CARD16 nbytesFilter; /* number of bytes in filter name */ + CARD16 pad B16; +} xRRSetCrtcTransformReq; + +#define sz_xRRSetCrtcTransformReq 48 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RRCrtc crtc B32; +} xRRGetCrtcTransformReq; + +#define sz_xRRGetCrtcTransformReq 8 + +typedef struct { + BYTE type; + CARD8 status; + CARD16 sequenceNumber B16; + CARD32 length B32; + xRenderTransform pendingTransform; + BYTE hasTransforms; + CARD8 pad0; + CARD16 pad1 B16; + xRenderTransform currentTransform; + CARD32 pad2 B32; + CARD16 pendingNbytesFilter B16; /* number of bytes in filter name */ + CARD16 pendingNparamsFilter B16; /* number of filter params */ + CARD16 currentNbytesFilter B16; /* number of bytes in filter name */ + CARD16 currentNparamsFilter B16; /* number of filter params */ +} xRRGetCrtcTransformReply; + +#define sz_xRRGetCrtcTransformReply 96 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + Window window B32; + RROutput output B32; +} xRRSetOutputPrimaryReq; + +#define sz_xRRSetOutputPrimaryReq 12 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + Window window B32; +} xRRGetOutputPrimaryReq; + +#define sz_xRRGetOutputPrimaryReq 8 + +typedef struct { + BYTE type; + CARD8 pad; + CARD16 sequenceNumber B16; + CARD32 length B32; + RROutput output B32; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xRRGetOutputPrimaryReply; + +#define sz_xRRGetOutputPrimaryReply 32 + +/* + * Additions for V1.4 + */ + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + Window window B32; +} xRRGetProvidersReq; + +#define sz_xRRGetProvidersReq 8 + +typedef struct { + BYTE type; + CARD8 pad; + CARD16 sequenceNumber B16; + CARD32 length B32; + Time timestamp B32; + CARD16 nProviders; + CARD16 pad1 B16; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xRRGetProvidersReply; + +#define sz_xRRGetProvidersReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RRProvider provider B32; + Time configTimestamp B32; +} xRRGetProviderInfoReq; + +#define sz_xRRGetProviderInfoReq 12 + +typedef struct { + BYTE type; + CARD8 status; + CARD16 sequenceNumber B16; + CARD32 length B32; + Time timestamp B32; + CARD32 capabilities B32; + CARD16 nCrtcs B16; + CARD16 nOutputs B16; + CARD16 nAssociatedProviders B16; + CARD16 nameLength B16; + CARD32 pad1 B32; + CARD32 pad2 B32; +} xRRGetProviderInfoReply; + +#define sz_xRRGetProviderInfoReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RRProvider provider B32; + RRProvider source_provider B32; + Time configTimestamp B32; +} xRRSetProviderOutputSourceReq; + +#define sz_xRRSetProviderOutputSourceReq 16 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RRProvider provider B32; + RRProvider sink_provider B32; + Time configTimestamp B32; +} xRRSetProviderOffloadSinkReq; + +#define sz_xRRSetProviderOffloadSinkReq 16 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RRProvider provider B32; +} xRRListProviderPropertiesReq; + +#define sz_xRRListProviderPropertiesReq 8 + +typedef struct { + BYTE type; + CARD8 pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 nAtoms B16; + CARD16 pad1 B16; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xRRListProviderPropertiesReply; + +#define sz_xRRListProviderPropertiesReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RRProvider provider B32; + Atom property B32; +} xRRQueryProviderPropertyReq; + +#define sz_xRRQueryProviderPropertyReq 12 + +typedef struct { + BYTE type; + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + BOOL pending; + BOOL range; + BOOL immutable; + BYTE pad1; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xRRQueryProviderPropertyReply; + +#define sz_xRRQueryProviderPropertyReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RRProvider provider B32; + Atom property B32; + BOOL pending; + BOOL range; + CARD16 pad B16; +} xRRConfigureProviderPropertyReq; + +#define sz_xRRConfigureProviderPropertyReq 16 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RRProvider provider B32; + Atom property B32; + Atom type B32; + CARD8 format; + CARD8 mode; + CARD16 pad; + CARD32 nUnits B32; +} xRRChangeProviderPropertyReq; + +#define sz_xRRChangeProviderPropertyReq 24 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RRProvider provider B32; + Atom property B32; +} xRRDeleteProviderPropertyReq; + +#define sz_xRRDeleteProviderPropertyReq 12 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RRProvider provider B32; + Atom property B32; + Atom type B32; + CARD32 longOffset B32; + CARD32 longLength B32; +#ifdef __cplusplus + BOOL _delete; +#else + BOOL delete; +#endif + BOOL pending; + CARD16 pad1 B16; +} xRRGetProviderPropertyReq; + +#define sz_xRRGetProviderPropertyReq 28 + +typedef struct { + BYTE type; + CARD8 format; + CARD16 sequenceNumber B16; + CARD32 length B32; + Atom propertyType B32; + CARD32 bytesAfter B32; + CARD32 nItems B32; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; +} xRRGetProviderPropertyReply; + +#define sz_xRRGetProviderPropertyReply 32 + /* * event */ @@ -644,8 +937,8 @@ typedef struct { CARD8 type; /* always evBase + RRNotify */ CARD8 subCode; /* RRNotify_OutputChange */ CARD16 sequenceNumber B16; - Time timestamp B32; /* time crtc was changed */ - Time configTimestamp B32; /* time crtc was changed */ + Time timestamp B32; /* time output was changed */ + Time configTimestamp B32; /* time config was changed */ Window window B32; /* window requesting notification */ RROutput output B32; /* affected output */ RRCrtc crtc B32; /* current crtc */ @@ -674,12 +967,190 @@ typedef struct { #define sz_xRROutputPropertyNotifyEvent 32 +typedef struct { + CARD8 type; /* always evBase + RRNotify */ + CARD8 subCode; /* RRNotify_ProviderChange */ + CARD16 sequenceNumber B16; + Time timestamp B32; /* time provider was changed */ + Window window B32; /* window requesting notification */ + RRProvider provider B32; /* affected provider */ + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; +} xRRProviderChangeNotifyEvent; + +#define sz_xRRProviderChangeNotifyEvent 32 + +typedef struct { + CARD8 type; /* always evBase + RRNotify */ + CARD8 subCode; /* RRNotify_ProviderProperty */ + CARD16 sequenceNumber B16; + Window window B32; /* window requesting notification */ + RRProvider provider B32; /* affected provider */ + Atom atom B32; /* property name */ + Time timestamp B32; /* time provider was changed */ + CARD8 state; /* NewValue or Deleted */ + CARD8 pad1; + CARD16 pad2 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; +} xRRProviderPropertyNotifyEvent; + +#define sz_xRRProviderPropertyNotifyEvent 32 + +typedef struct { + CARD8 type; /* always evBase + RRNotify */ + CARD8 subCode; /* RRNotify_ResourceChange */ + CARD16 sequenceNumber B16; + Time timestamp B32; /* time resource was changed */ + Window window B32; /* window requesting notification */ + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xRRResourceChangeNotifyEvent; + +#define sz_xRRResourceChangeNotifyEvent 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RRCrtc crtc B32; +} xRRGetPanningReq; + +#define sz_xRRGetPanningReq 8 + +typedef struct { + BYTE type; + CARD8 status; + CARD16 sequenceNumber B16; + CARD32 length B32; + Time timestamp B32; + CARD16 left B16; + CARD16 top B16; + CARD16 width B16; + CARD16 height B16; + CARD16 track_left B16; + CARD16 track_top B16; + CARD16 track_width B16; + CARD16 track_height B16; + INT16 border_left B16; + INT16 border_top B16; + INT16 border_right B16; + INT16 border_bottom B16; +} xRRGetPanningReply; + +#define sz_xRRGetPanningReply 36 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RRCrtc crtc B32; + Time timestamp B32; + CARD16 left B16; + CARD16 top B16; + CARD16 width B16; + CARD16 height B16; + CARD16 track_left B16; + CARD16 track_top B16; + CARD16 track_width B16; + CARD16 track_height B16; + INT16 border_left B16; + INT16 border_top B16; + INT16 border_right B16; + INT16 border_bottom B16; +} xRRSetPanningReq; + +#define sz_xRRSetPanningReq 36 + +typedef struct { + BYTE type; + CARD8 status; + CARD16 sequenceNumber B16; + CARD32 length B32; + Time newTimestamp B32; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xRRSetPanningReply; + +#define sz_xRRSetPanningReply 32 + +typedef struct { + Atom name B32; + BOOL primary; + BOOL automatic; + CARD16 noutput B16; + INT16 x B16; + INT16 y B16; + CARD16 width B16; + CARD16 height B16; + CARD32 widthInMillimeters B32; + CARD32 heightInMillimeters B32; +} xRRMonitorInfo; + +#define sz_xRRMonitorInfo 24 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + Window window B32; + BOOL get_active; + CARD8 pad; + CARD16 pad2; +} xRRGetMonitorsReq; + +#define sz_xRRGetMonitorsReq 12 + +typedef struct { + BYTE type; + CARD8 status; + CARD16 sequenceNumber B16; + CARD32 length B32; + Time timestamp B32; + CARD32 nmonitors B32; + CARD32 noutputs B32; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; +} xRRGetMonitorsReply; + +#define sz_xRRGetMonitorsReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + Window window B32; + xRRMonitorInfo monitor; +} xRRSetMonitorReq; + +#define sz_xRRSetMonitorReq 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + Window window B32; + Atom name B32; +} xRRDeleteMonitorReq; + +#define sz_xRRDeleteMonitorReq 12 + #undef RRModeFlags #undef RRCrtc #undef RRMode #undef RROutput #undef RRMode #undef RRCrtc +#undef RRProvider #undef Drawable #undef Window #undef Font @@ -694,5 +1165,6 @@ typedef struct { #undef Rotation #undef SizeID #undef SubpixelOrder +#undef Atom #endif /* _XRANDRP_H_ */ diff --git a/nx-X11/programs/Xserver/randr/randrstr.h b/nx-X11/programs/Xserver/randr/randrstr.h index 8e9107c9f..1bd0b9535 100644 --- a/nx-X11/programs/Xserver/randr/randrstr.h +++ b/nx-X11/programs/Xserver/randr/randrstr.h @@ -2,6 +2,7 @@ * Copyright © 2000 Compaq Computer Corporation * Copyright © 2002 Hewlett-Packard Company * Copyright © 2006 Intel Corporation + * Copyright © 2008 Red Hat, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -32,6 +33,10 @@ #ifndef _RANDRSTR_H_ #define _RANDRSTR_H_ +#ifndef NXAGENT_SERVER +#include "list.h" +#endif + #include #include #include "misc.h" @@ -43,26 +48,26 @@ #include "pixmapstr.h" #include "extnsionst.h" #include "servermd.h" -#ifndef NXAGENT_SERVER -#include -#include -#else +#include "rrtransform.h" #include "randr.h" #include "randrproto.h" -#endif -#ifdef RENDER #include /* we share subpixel order information */ #include "picturestr.h" -#endif #include /* required for ABI compatibility for now */ #define RANDR_10_INTERFACE 1 #define RANDR_12_INTERFACE 1 +#define RANDR_13_INTERFACE 1 /* requires RANDR_12_INTERFACE */ +#define RANDR_15_INTERFACE 1 +#define RANDR_GET_CRTC_INTERFACE 1 + +#define RANDR_INTERFACE_VERSION 0x0104 typedef XID RRMode; typedef XID RROutput; typedef XID RRCrtc; +typedef XID RRProvider; extern int RREventBase, RRErrorBase; @@ -79,6 +84,8 @@ typedef struct _rrPropertyValue RRPropertyValueRec, *RRPropertyValuePtr; typedef struct _rrProperty RRPropertyRec, *RRPropertyPtr; typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr; typedef struct _rrOutput RROutputRec, *RROutputPtr; +typedef struct _rrProvider RRProviderRec, *RRProviderPtr; +typedef struct _rrMonitor RRMonitorRec, *RRMonitorPtr; struct _rrMode { int refcnt; @@ -120,6 +127,14 @@ struct _rrCrtc { CARD16 *gammaBlue; CARD16 *gammaGreen; void *devPrivate; + Bool transforms; + RRTransformRec client_pending_transform; + RRTransformRec client_current_transform; + PictTransform transform; + struct pict_f_transform f_transform; + struct pict_f_transform f_inverse; + + PixmapPtr scanout_pixmap; }; struct _rrOutput { @@ -147,6 +162,35 @@ struct _rrOutput { void *devPrivate; }; +struct _rrProvider { + RRProvider id; + ScreenPtr pScreen; + uint32_t capabilities; + char *name; + int nameLength; + RRPropertyPtr properties; + Bool pendingProperties; + Bool changed; + struct _rrProvider *offload_sink; + struct _rrProvider *output_source; +}; + +typedef struct _rrMonitorGeometry { + BoxRec box; + CARD32 mmWidth; + CARD32 mmHeight; +} RRMonitorGeometryRec, *RRMonitorGeometryPtr; + +struct _rrMonitor { + Atom name; + ScreenPtr pScreen; + int numOutputs; + RROutput *outputs; + Bool primary; + Bool automatic; + RRMonitorGeometryRec geometry; +}; + #if RANDR_12_INTERFACE typedef Bool (*RRScreenSetSizeProcPtr) (ScreenPtr pScreen, CARD16 width, @@ -163,6 +207,8 @@ typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr pScreen, typedef Bool (*RRCrtcSetGammaProcPtr) (ScreenPtr pScreen, RRCrtcPtr crtc); +typedef Bool (*RRCrtcGetGammaProcPtr) (ScreenPtr pScreen, RRCrtcPtr crtc); + typedef Bool (*RROutputSetPropertyProcPtr) (ScreenPtr pScreen, RROutputPtr output, Atom property, @@ -176,8 +222,41 @@ typedef void (*RRModeDestroyProcPtr) (ScreenPtr pScreen, RRModePtr mode); #endif +#if RANDR_13_INTERFACE +typedef Bool (*RROutputGetPropertyProcPtr) (ScreenPtr pScreen, + RROutputPtr output, Atom property); +typedef Bool (*RRGetPanningProcPtr) (ScreenPtr pScrn, + RRCrtcPtr crtc, + BoxPtr totalArea, + BoxPtr trackingArea, INT16 *border); +typedef Bool (*RRSetPanningProcPtr) (ScreenPtr pScrn, + RRCrtcPtr crtc, + BoxPtr totalArea, + BoxPtr trackingArea, INT16 *border); + +#endif /* RANDR_13_INTERFACE */ + +typedef Bool (*RRProviderGetPropertyProcPtr) (ScreenPtr pScreen, + RRProviderPtr provider, + Atom property); +typedef Bool (*RRProviderSetPropertyProcPtr) (ScreenPtr pScreen, + RRProviderPtr provider, + Atom property, + RRPropertyValuePtr value); + typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation * rotations); -typedef Bool (*RRCloseScreenProcPtr) (int i, ScreenPtr pscreen); +typedef Bool (*RRCloseScreenProcPtr) (ScreenPtr pscreen); + +typedef Bool (*RRProviderSetOutputSourceProcPtr) (ScreenPtr pScreen, + RRProviderPtr provider, + RRProviderPtr output_source); + +typedef Bool (*RRProviderSetOffloadSinkProcPtr) (ScreenPtr pScreen, + RRProviderPtr provider, + RRProviderPtr offload_sink); + +typedef void (*RRProviderDestroyProcPtr) (ScreenPtr pScreen, + RRProviderPtr provider); /* These are for 1.0 compatibility */ @@ -202,6 +281,8 @@ typedef Bool (*RRSetConfigProcPtr) (ScreenPtr pScreen, #endif +typedef Bool (*RRCrtcSetScanoutPixmapProcPtr) (RRCrtcPtr crtc, PixmapPtr pixmap); + typedef struct _rrScrPriv { /* * 'public' part of the structure; DDXen fill this in @@ -215,10 +296,23 @@ typedef struct _rrScrPriv { RRScreenSetSizeProcPtr rrScreenSetSize; RRCrtcSetProcPtr rrCrtcSet; RRCrtcSetGammaProcPtr rrCrtcSetGamma; + RRCrtcGetGammaProcPtr rrCrtcGetGamma; RROutputSetPropertyProcPtr rrOutputSetProperty; RROutputValidateModeProcPtr rrOutputValidateMode; RRModeDestroyProcPtr rrModeDestroy; #endif +#if RANDR_13_INTERFACE + RROutputGetPropertyProcPtr rrOutputGetProperty; + RRGetPanningProcPtr rrGetPanning; + RRSetPanningProcPtr rrSetPanning; +#endif + /* TODO #if RANDR_15_INTERFACE */ + RRCrtcSetScanoutPixmapProcPtr rrCrtcSetScanoutPixmap; + + RRProviderSetOutputSourceProcPtr rrProviderSetOutputSource; + RRProviderSetOffloadSinkProcPtr rrProviderSetOffloadSink; + RRProviderGetPropertyProcPtr rrProviderGetProperty; + RRProviderSetPropertyProcPtr rrProviderSetProperty; /* * Private part of the structure; not considered part of the ABI @@ -230,6 +324,7 @@ typedef struct _rrScrPriv { Bool changed; /* some config changed */ Bool configChanged; /* configuration changed */ Bool layoutChanged; /* screen layout changed */ + Bool resourcesChanged; /* screen resources change */ CARD16 minWidth, minHeight; CARD16 maxWidth, maxHeight; @@ -238,6 +333,7 @@ typedef struct _rrScrPriv { int numOutputs; RROutputPtr *outputs; + RROutputPtr primaryOutput; int numCrtcs; RRCrtcPtr *crtcs; @@ -259,9 +355,21 @@ typedef struct _rrScrPriv { int rate; int size; #endif + Bool discontiguous; + + RRProviderPtr provider; + + RRProviderDestroyProcPtr rrProviderDestroy; + + int numMonitors; + RRMonitorPtr *monitors; + } rrScrPrivRec, *rrScrPrivPtr; #ifndef NXAGENT_SERVER +extern _X_EXPORT DevPrivateKeyRec rrPrivKeyRec; + +#define rrPrivKey (&rrPrivKeyRec) extern DevPrivateKey rrPrivKey; #else extern int rrPrivIndex; @@ -269,17 +377,17 @@ extern int rrPrivIndex; #ifndef NXAGENT_SERVER -#define rrGetScrPriv(pScr) ((rrScrPrivPtr)dixLookupPrivate(&(pScr)->devPrivates, rrPrivKey)) -#define rrScrPriv(pScr) rrScrPrivPtr pScrPriv = rrGetScrPriv(pScr) +#define rrGetScrPriv(pScr) ((rrScrPrivPtr)dixLookupPrivate(&(pScr)->devPrivates, rrPrivKey)) +#define rrScrPriv(pScr) rrScrPrivPtr pScrPriv = rrGetScrPriv(pScr) #define SetRRScreen(s,p) dixSetPrivate(&(s)->devPrivates, rrPrivKey, p) -#else +#else /* !defined(NXAGENT_SERVER) */ -#define rrGetScrPriv(pScr) ((rrScrPrivPtr) (pScr)->devPrivates[rrPrivIndex].ptr) -#define rrScrPriv(pScr) rrScrPrivPtr pScrPriv = rrGetScrPriv(pScr) +#define rrGetScrPriv(pScr) ((rrScrPrivPtr) (pScr)->devPrivates[rrPrivIndex].ptr) +#define rrScrPriv(pScr) rrScrPrivPtr pScrPriv = rrGetScrPriv(pScr) #define SetRRScreen(s,p) ((s)->devPrivates[rrPrivIndex].ptr = (void *) (p)) -#endif +#endif /* !defined(NXAGENT_SERVER) */ /* * each window has a list of clients requesting @@ -317,43 +425,132 @@ extern DevPrivateKey RRClientPrivateKey; #else extern int RRClientPrivateIndex; #endif -extern RESTYPE RRCrtcType, RRModeType, RROutputType; + +extern _X_EXPORT RESTYPE RRCrtcType, RRModeType, RROutputType, RRProviderType; + +#ifdef NXAGENT_SERVER #define LookupOutput(client,id,a) ((RROutputPtr) \ - (SecurityLookupIDByType (client, id, \ - RROutputType, a))) + (SecurityLookupIDByType (client, id, \ + RROutputType, a))) #define LookupCrtc(client,id,a) ((RRCrtcPtr) \ - (SecurityLookupIDByType (client, id, \ - RRCrtcType, a))) + (SecurityLookupIDByType (client, id, \ + RRCrtcType, a))) #define LookupMode(client,id,a) ((RRModePtr) \ - (SecurityLookupIDByType (client, id, \ - RRModeType, a))) -#ifndef NXAGENT_SERVER - -#define GetRRClient(pClient) ((RRClientPtr)dixLookupPrivate(&(pClient)->devPrivates, RRClientPrivateKey)) -#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient) - -#else - -#define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr) -#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient) + (SecurityLookupIDByType (client, id, \ + RRModeType, a))) +#define LookupProvider(client,id,a) ((RRProviderPtr) \ + (SecurityLookupIDByType (client, id, \ + RRProviderType, a))) #define DixUnknownAccess SecurityUnknownAccess #define DixReadAccess SecurityReadAccess #define DixWriteAccess SecurityWriteAccess +#define DixSetAttrAccess SecurityWriteAccess +#define DixUseAccess SecurityWriteAccess #define DixDestroyAccess SecurityDestroyAccess #endif +#ifndef NXAGENT_SERVER + +#define RRClientPrivateKey (&RRClientPrivateKeyRec) +#define GetRRClient(pClient) ((RRClientPtr)dixLookupPrivate(&(pClient)->devPrivates, RRClientPrivateKey)) + +#else /* !defined/NXAGENT_SERVER) */ + +#define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr) + +#endif /* !defined(NXAGENT_SERVER) */ +#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient) + /* Initialize the extension */ void RRExtensionInit(void); +#ifndef NXAGENT_SERVER +#define VERIFY_RR_OUTPUT(id, ptr, a)\ + {\ + int rc = dixLookupResourceByType((void **)&(ptr), id,\ + RROutputType, client, a);\ + if (rc != Success) {\ + client->errorValue = id;\ + return rc;\ + }\ + } + +#define VERIFY_RR_CRTC(id, ptr, a)\ + {\ + int rc = dixLookupResourceByType((void **)&(ptr), id,\ + RRCrtcType, client, a);\ + if (rc != Success) {\ + client->errorValue = id;\ + return rc;\ + }\ + } + +#define VERIFY_RR_MODE(id, ptr, a)\ + {\ + int rc = dixLookupResourceByType((void **)&(ptr), id,\ + RRModeType, client, a);\ + if (rc != Success) {\ + client->errorValue = id;\ + return rc;\ + }\ + } + +#define VERIFY_RR_PROVIDER(id, ptr, a)\ + {\ + int rc = dixLookupResourceByType((void **)&(ptr), id,\ + RRProviderType, client, a);\ + if (rc != Success) {\ + client->errorValue = id;\ + return rc;\ + }\ + } +#else /* !defined(NXAGENT_SERVER) */ +#define VERIFY_RR_OUTPUT(id, ptr, a)\ + {\ + ptr = LookupOutput(client, id, a);\ + if (!ptr) {\ + client->errorValue = id;\ + return RRErrorBase + BadRROutput;\ + }\ + } + +#define VERIFY_RR_CRTC(id, ptr, a)\ + {\ + ptr = LookupCrtc (client, id, a);\ + if (!ptr) {\ + client->errorValue = id;\ + return RRErrorBase + BadRRCrtc;\ + }\ + } + +#define VERIFY_RR_MODE(id, ptr, a)\ + {\ + ptr = LookupMode (client, id, a);\ + if (!ptr) {\ + client->errorValue = id;\ + return RRErrorBase + BadRRMode;\ + }\ + } + +#define VERIFY_RR_PROVIDER(id, ptr, a)\ + {\ + ptr = LookupProvider (client, id, a);\ + if (!ptr) {\ + client->errorValue = id;\ + return RRErrorBase + BadRRProvider;\ + }\ + } +#endif /* !defined(NXAGENT_SERVER) */ + #ifdef RANDR_12_INTERFACE /* * Set the range of sizes for the screen */ -void +extern _X_EXPORT void RRScreenSetSizeRange(ScreenPtr pScreen, CARD16 minWidth, @@ -366,13 +563,13 @@ RRScreenSetSizeRange(ScreenPtr pScreen, * The driver is responsible for calling this whenever it has changed * the size of the screen */ -void +extern _X_EXPORT void RRScreenSizeNotify(ScreenPtr pScreen); /* * Request that the screen be resized */ -Bool +extern _X_EXPORT Bool RRScreenSizeSet(ScreenPtr pScreen, CARD16 width, CARD16 height, CARD32 mmWidth, CARD32 mmHeight); @@ -380,85 +577,63 @@ RRScreenSizeSet(ScreenPtr pScreen, /* * Send ConfigureNotify event to root window when 'something' happens */ -void +extern _X_EXPORT void RRSendConfigNotify(ScreenPtr pScreen); /* * screen dispatch */ -int +extern _X_EXPORT int ProcRRGetScreenSizeRange(ClientPtr client); -int +extern _X_EXPORT int ProcRRSetScreenSize(ClientPtr client); -int +extern _X_EXPORT int ProcRRGetScreenResources(ClientPtr client); -int +extern _X_EXPORT int + ProcRRGetScreenResourcesCurrent(ClientPtr client); + +extern _X_EXPORT int ProcRRSetScreenConfig(ClientPtr client); -int +extern _X_EXPORT int ProcRRGetScreenInfo(ClientPtr client); /* * Deliver a ScreenNotify event */ -void +extern _X_EXPORT void RRDeliverScreenEvent(ClientPtr client, WindowPtr pWin, ScreenPtr pScreen); -/* mirandr.c */ -Bool - miRandRInit(ScreenPtr pScreen); - -Bool - miRRGetInfo(ScreenPtr pScreen, Rotation * rotations); - -Bool - miRRGetScreenInfo(ScreenPtr pScreen); - -Bool - -miRRCrtcSet(ScreenPtr pScreen, - RRCrtcPtr crtc, - RRModePtr mode, - int x, - int y, Rotation rotation, int numOutput, RROutputPtr * outputs); - -Bool - -miRROutputSetProperty(ScreenPtr pScreen, - RROutputPtr output, - Atom property, RRPropertyValuePtr value); - -Bool - miRROutputValidateMode(ScreenPtr pScreen, RROutputPtr output, RRModePtr mode); - -void - miRRModeDestroy(ScreenPtr pScreen, RRModePtr mode); +extern _X_EXPORT void + RRResourcesChanged(ScreenPtr pScreen); /* randr.c */ +/* set a screen change on the primary screen */ +extern _X_EXPORT void + RRSetChanged(ScreenPtr pScreen); + /* * Send all pending events */ -void +extern _X_EXPORT void RRTellChanged(ScreenPtr pScreen); /* * Poll the driver for changed information */ -Bool - RRGetInfo(ScreenPtr pScreen); +extern _X_EXPORT Bool + RRGetInfo(ScreenPtr pScreen, Bool force_query); -Bool RRInit(void); +extern _X_EXPORT Bool RRInit(void); -Bool RRScreenInit(ScreenPtr pScreen); +extern _X_EXPORT Bool RRScreenInit(ScreenPtr pScreen); -RROutputPtr RRFirstOutput(ScreenPtr pScreen); +extern _X_EXPORT RROutputPtr RRFirstOutput(ScreenPtr pScreen); -Rotation RRGetRotation(ScreenPtr pScreen); - -CARD16 +extern _X_EXPORT CARD16 RRVerticalRefresh(xRRModeInfo * mode); #ifdef RANDR_10_INTERFACE @@ -471,29 +646,24 @@ CARD16 * Then, register the specific size with the screen */ -RRScreenSizePtr +extern _X_EXPORT RRScreenSizePtr RRRegisterSize(ScreenPtr pScreen, short width, short height, short mmWidth, short mmHeight); -Bool RRRegisterRate(ScreenPtr pScreen, RRScreenSizePtr pSize, int rate); +extern _X_EXPORT Bool + RRRegisterRate(ScreenPtr pScreen, RRScreenSizePtr pSize, int rate); /* * Finally, set the current configuration of the screen */ -void +extern _X_EXPORT void + RRSetCurrentConfig(ScreenPtr pScreen, Rotation rotation, int rate, RRScreenSizePtr pSize); -Bool RRScreenInit(ScreenPtr pScreen); - -Rotation RRGetRotation(ScreenPtr pScreen); - -int - -RRSetScreenConfig(ScreenPtr pScreen, - Rotation rotation, int rate, RRScreenSizePtr pSize); +extern _X_EXPORT Rotation RRGetRotation(ScreenPtr pScreen); #endif @@ -503,38 +673,46 @@ RRSetScreenConfig(ScreenPtr pScreen, * Notify the CRTC of some change; layoutChanged indicates that * some position or size element changed */ -void +extern _X_EXPORT void RRCrtcChanged(RRCrtcPtr crtc, Bool layoutChanged); /* * Create a CRTC */ -RRCrtcPtr RRCrtcCreate(ScreenPtr pScreen, void *devPrivate); +extern _X_EXPORT RRCrtcPtr RRCrtcCreate(ScreenPtr pScreen, void *devPrivate); /* * Set the allowed rotations on a CRTC */ -void +extern _X_EXPORT void RRCrtcSetRotations(RRCrtcPtr crtc, Rotation rotations); +/* + * Set whether transforms are allowed on a CRTC + */ +extern _X_EXPORT void + RRCrtcSetTransformSupport(RRCrtcPtr crtc, Bool transforms); + /* * Notify the extension that the Crtc has been reconfigured, * the driver calls this whenever it has updated the mode */ -Bool +extern _X_EXPORT Bool RRCrtcNotify(RRCrtcPtr crtc, RRModePtr mode, int x, - int y, Rotation rotation, int numOutputs, RROutputPtr * outputs); + int y, + Rotation rotation, + RRTransformPtr transform, int numOutputs, RROutputPtr * outputs); -void +extern _X_EXPORT void RRDeliverCrtcEvent(ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc); /* * Request that the Crtc be reconfigured */ -Bool +extern _X_EXPORT Bool RRCrtcSet(RRCrtcPtr crtc, RRModePtr mode, @@ -545,23 +723,31 @@ RRCrtcSet(RRCrtcPtr crtc, * Request that the Crtc gamma be changed */ -Bool +extern _X_EXPORT Bool RRCrtcGammaSet(RRCrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue); +/* + * Request current gamma back from the DDX (if possible). + * This includes gamma size. + */ + +extern _X_EXPORT Bool + RRCrtcGammaGet(RRCrtcPtr crtc); + /* * Notify the extension that the Crtc gamma has been changed * The driver calls this whenever it has changed the gamma values * in the RRCrtcRec */ -Bool +extern _X_EXPORT Bool RRCrtcGammaNotify(RRCrtcPtr crtc); /* * Set the size of the gamma table at server startup time */ -Bool +extern _X_EXPORT Bool RRCrtcGammaSetSize(RRCrtcPtr crtc, int size); /* @@ -569,42 +755,99 @@ Bool * taking into account the current mode and rotation */ -void +extern _X_EXPORT void RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height); +/* + * Return crtc transform + */ +extern _X_EXPORT RRTransformPtr RRCrtcGetTransform(RRCrtcPtr crtc); + +/* + * Check whether the pending and current transforms are the same + */ +extern _X_EXPORT Bool + RRCrtcPendingTransform(RRCrtcPtr crtc); + /* * Destroy a Crtc at shutdown */ -void +extern _X_EXPORT void RRCrtcDestroy(RRCrtcPtr crtc); +/* + * Set the pending CRTC transformation + */ + +extern _X_EXPORT int + +RRCrtcTransformSet(RRCrtcPtr crtc, + PictTransformPtr transform, + struct pict_f_transform *f_transform, + struct pict_f_transform *f_inverse, + char *filter, int filter_len, xFixed * params, int nparams); + /* * Initialize crtc type */ -Bool +extern _X_EXPORT Bool RRCrtcInit(void); +/* + * Initialize crtc type error value + */ +extern _X_EXPORT void + RRCrtcInitErrorValue(void); + +/* + * Detach and free a scanout pixmap + */ +extern _X_EXPORT void + RRCrtcDetachScanoutPixmap(RRCrtcPtr crtc); + +extern _X_EXPORT Bool + RRReplaceScanoutPixmap(DrawablePtr pDrawable, PixmapPtr pPixmap, Bool enable); + /* * Crtc dispatch */ -int +extern _X_EXPORT int ProcRRGetCrtcInfo(ClientPtr client); -int +extern _X_EXPORT int ProcRRSetCrtcConfig(ClientPtr client); -int +extern _X_EXPORT int ProcRRGetCrtcGammaSize(ClientPtr client); -int +extern _X_EXPORT int ProcRRGetCrtcGamma(ClientPtr client); -int +extern _X_EXPORT int ProcRRSetCrtcGamma(ClientPtr client); +extern _X_EXPORT int + ProcRRSetCrtcTransform(ClientPtr client); + +extern _X_EXPORT int + ProcRRGetCrtcTransform(ClientPtr client); + +int + ProcRRGetPanning(ClientPtr client); + +int + ProcRRSetPanning(ClientPtr client); + +void + RRConstrainCursorHarder( +#ifndef NXAGENT_SERVER + DeviceIntPtr, +#endif /* !defined(NXAGENT_SERVER) */ + ScreenPtr, int, int *, int *); + /* rrdispatch.c */ -Bool +extern _X_EXPORT Bool RRClientKnowsRates(ClientPtr pClient); /* rrmode.c */ @@ -612,39 +855,42 @@ Bool * Find, and if necessary, create a mode */ -RRModePtr RRModeGet(xRRModeInfo * modeInfo, const char *name); - -void - RRModePruneUnused(ScreenPtr pScreen); +extern _X_EXPORT RRModePtr RRModeGet(xRRModeInfo * modeInfo, const char *name); /* * Destroy a mode. */ -void +extern _X_EXPORT void RRModeDestroy(RRModePtr mode); /* * Return a list of modes that are valid for some output in pScreen */ -RRModePtr *RRModesForScreen(ScreenPtr pScreen, int *num_ret); +extern _X_EXPORT RRModePtr *RRModesForScreen(ScreenPtr pScreen, int *num_ret); /* * Initialize mode type */ -Bool +extern _X_EXPORT Bool RRModeInit(void); -int +/* + * Initialize mode type error value + */ +extern _X_EXPORT void + RRModeInitErrorValue(void); + +extern _X_EXPORT int ProcRRCreateMode(ClientPtr client); -int +extern _X_EXPORT int ProcRRDestroyMode(ClientPtr client); -int +extern _X_EXPORT int ProcRRAddOutputMode(ClientPtr client); -int +extern _X_EXPORT int ProcRRDeleteOutputMode(ClientPtr client); /* rroutput.c */ @@ -655,116 +901,245 @@ int * has changed, or whether the change was strictly internal * (which crtc is in use) */ -void +extern _X_EXPORT void RROutputChanged(RROutputPtr output, Bool configChanged); /* * Create an output */ -RROutputPtr +extern _X_EXPORT RROutputPtr RROutputCreate(ScreenPtr pScreen, const char *name, int nameLength, void *devPrivate); /* * Notify extension that output parameters have been changed */ -Bool +extern _X_EXPORT Bool RROutputSetClones(RROutputPtr output, RROutputPtr * clones, int numClones); -Bool +extern _X_EXPORT Bool RROutputSetModes(RROutputPtr output, RRModePtr * modes, int numModes, int numPreferred); -int +extern _X_EXPORT int RROutputAddUserMode(RROutputPtr output, RRModePtr mode); -int +extern _X_EXPORT int RROutputDeleteUserMode(RROutputPtr output, RRModePtr mode); -Bool +extern _X_EXPORT Bool RROutputSetCrtcs(RROutputPtr output, RRCrtcPtr * crtcs, int numCrtcs); -Bool +extern _X_EXPORT Bool RROutputSetConnection(RROutputPtr output, CARD8 connection); -Bool +extern _X_EXPORT Bool RROutputSetSubpixelOrder(RROutputPtr output, int subpixelOrder); -Bool +extern _X_EXPORT Bool RROutputSetPhysicalSize(RROutputPtr output, int mmWidth, int mmHeight); -void +extern _X_EXPORT void RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output); -void +extern _X_EXPORT void RROutputDestroy(RROutputPtr output); -int +extern _X_EXPORT int ProcRRGetOutputInfo(ClientPtr client); +extern _X_EXPORT int + ProcRRSetOutputPrimary(ClientPtr client); + +extern _X_EXPORT int + ProcRRGetOutputPrimary(ClientPtr client); + /* * Initialize output type */ -Bool +extern _X_EXPORT Bool RROutputInit(void); +/* + * Initialize output type error value + */ +extern _X_EXPORT void + RROutputInitErrorValue(void); + /* rrpointer.c */ -void +extern _X_EXPORT void RRPointerMoved(ScreenPtr pScreen, int x, int y); -void +extern _X_EXPORT void RRPointerScreenConfigured(ScreenPtr pScreen); /* rrproperty.c */ -void +extern _X_EXPORT void RRDeleteAllOutputProperties(RROutputPtr output); -RRPropertyValuePtr +extern _X_EXPORT RRPropertyValuePtr RRGetOutputProperty(RROutputPtr output, Atom property, Bool pending); -RRPropertyPtr RRQueryOutputProperty(RROutputPtr output, Atom property); +extern _X_EXPORT RRPropertyPtr +RRQueryOutputProperty(RROutputPtr output, Atom property); -void +extern _X_EXPORT void RRDeleteOutputProperty(RROutputPtr output, Atom property); -Bool +extern _X_EXPORT Bool RRPostPendingProperties(RROutputPtr output); -int +extern _X_EXPORT int RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type, int format, int mode, unsigned long len, void *value, Bool sendevent, Bool pending); -int +extern _X_EXPORT int RRConfigureOutputProperty(RROutputPtr output, Atom property, Bool pending, Bool range, Bool immutable, int num_values, INT32 *values); -int +extern _X_EXPORT int ProcRRChangeOutputProperty(ClientPtr client); -int +extern _X_EXPORT int ProcRRGetOutputProperty(ClientPtr client); -int +extern _X_EXPORT int ProcRRListOutputProperties(ClientPtr client); -int +extern _X_EXPORT int ProcRRQueryOutputProperty(ClientPtr client); -int +extern _X_EXPORT int ProcRRConfigureOutputProperty(ClientPtr client); -int +extern _X_EXPORT int ProcRRDeleteOutputProperty(ClientPtr client); +/* rrprovider.c */ +extern _X_EXPORT void + RRProviderInitErrorValue(void); + +extern _X_EXPORT int + ProcRRGetProviders(ClientPtr client); + +extern _X_EXPORT int + ProcRRGetProviderInfo(ClientPtr client); + +extern _X_EXPORT int + ProcRRSetProviderOutputSource(ClientPtr client); + +extern _X_EXPORT int + ProcRRSetProviderOffloadSink(ClientPtr client); + +extern _X_EXPORT Bool + RRProviderInit(void); + +extern _X_EXPORT RRProviderPtr +RRProviderCreate(ScreenPtr pScreen, const char *name, int nameLength); + +extern _X_EXPORT void + RRProviderDestroy(RRProviderPtr provider); + +extern _X_EXPORT void + RRProviderSetCapabilities(RRProviderPtr provider, uint32_t capabilities); + +extern _X_EXPORT Bool + RRProviderLookup(XID id, RRProviderPtr * provider_p); + +extern _X_EXPORT void + +RRDeliverProviderEvent(ClientPtr client, WindowPtr pWin, RRProviderPtr provider); + +/* rrproviderproperty.c */ + +extern _X_EXPORT void + RRDeleteAllProviderProperties(RRProviderPtr provider); + +extern _X_EXPORT RRPropertyValuePtr +RRGetProviderProperty(RRProviderPtr provider, Atom property, Bool pending); + +extern _X_EXPORT RRPropertyPtr +RRQueryProviderProperty(RRProviderPtr provider, Atom property); + +extern _X_EXPORT void + RRDeleteProviderProperty(RRProviderPtr provider, Atom property); + +extern _X_EXPORT int +RRChangeProviderProperty(RRProviderPtr provider, Atom property, Atom type, + int format, int mode, unsigned long len, + void *value, Bool sendevent, Bool pending); + +extern _X_EXPORT int +RRConfigureProviderProperty(RRProviderPtr provider, Atom property, + Bool pending, Bool range, Bool immutable, + int num_values, INT32 *values); + +extern _X_EXPORT Bool + RRPostProviderPendingProperties(RRProviderPtr provider); + +extern _X_EXPORT int + ProcRRGetProviderProperty(ClientPtr client); + +extern _X_EXPORT int + ProcRRListProviderProperties(ClientPtr client); + +extern _X_EXPORT int + ProcRRQueryProviderProperty(ClientPtr client); + +extern _X_EXPORT int + ProcRRConfigureProviderProperty(ClientPtr client); + +extern _X_EXPORT int + ProcRRChangeProviderProperty(ClientPtr client); + +extern _X_EXPORT int + ProcRRDeleteProviderProperty(ClientPtr client); + /* rrxinerama.c */ -void +#ifdef XINERAMA +extern _X_EXPORT void RRXineramaExtensionInit(void); +#endif + +void + RRMonitorInit(ScreenPtr screen); + +Bool + +RRMonitorMakeList(ScreenPtr screen, Bool get_active, RRMonitorPtr * monitors_ret, int *nmon_ret); + +int + RRMonitorCountList(ScreenPtr screen); + +void + RRMonitorFreeList(RRMonitorPtr monitors, int nmon); + +void + RRMonitorClose(ScreenPtr screen); + +RRMonitorPtr +RRMonitorAlloc(int noutput); + +int + RRMonitorAdd(ClientPtr client, ScreenPtr screen, RRMonitorPtr monitor); + +void + RRMonitorFree(RRMonitorPtr monitor); + +int + ProcRRGetMonitors(ClientPtr client); + +int + ProcRRSetMonitor(ClientPtr client); + +int + ProcRRDeleteMonitor(ClientPtr client); #endif /* _RANDRSTR_H_ */ diff --git a/nx-X11/programs/Xserver/randr/rrcrtc.c b/nx-X11/programs/Xserver/randr/rrcrtc.c index 76b4c64f9..d69b5ec08 100644 --- a/nx-X11/programs/Xserver/randr/rrcrtc.c +++ b/nx-X11/programs/Xserver/randr/rrcrtc.c @@ -1,5 +1,6 @@ /* * Copyright © 2006 Keith Packard + * Copyright 2010 Red Hat, Inc * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -39,7 +40,7 @@ #include "randrstr.h" #include "swaprep.h" -#include "registry.h" +#include "mipointer.h" RESTYPE RRCrtcType; @@ -55,7 +56,7 @@ RRCrtcChanged(RRCrtcPtr crtc, Bool layoutChanged) if (pScreen) { rrScrPriv(pScreen); - pScrPriv->changed = TRUE; + RRSetChanged(pScreen); /* * Send ConfigureNotify on any layout change */ @@ -81,8 +82,13 @@ RRCrtcCreate(ScreenPtr pScreen, void *devPrivate) /* make space for the crtc pointer */ if (pScrPriv->numCrtcs) +#ifndef NXAGENT_SERVER + crtcs = reallocarray(pScrPriv->crtcs, + pScrPriv->numCrtcs + 1, sizeof(RRCrtcPtr)); +#else /* !defined(NXAGENT_SERVER) */ crtcs = xrealloc(pScrPriv->crtcs, (pScrPriv->numCrtcs + 1) * sizeof(RRCrtcPtr)); +#endif /* !defined(NXAGENT_SERVER) */ else crtcs = xalloc(sizeof(RRCrtcPtr)); if (!crtcs) @@ -105,6 +111,11 @@ RRCrtcCreate(ScreenPtr pScreen, void *devPrivate) crtc->gammaRed = crtc->gammaBlue = crtc->gammaGreen = NULL; crtc->changed = FALSE; crtc->devPrivate = devPrivate; + RRTransformInit(&crtc->client_pending_transform); + RRTransformInit(&crtc->client_current_transform); + pixman_transform_init_identity(&crtc->transform); + pixman_f_transform_init_identity(&crtc->f_transform); + pixman_f_transform_init_identity(&crtc->f_inverse); if (!AddResource(crtc->id, RRCrtcType, (void *) crtc)) return NULL; @@ -113,6 +124,8 @@ RRCrtcCreate(ScreenPtr pScreen, void *devPrivate) crtc->pScreen = pScreen; pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc; + RRResourcesChanged(pScreen); + return crtc; } @@ -125,6 +138,15 @@ RRCrtcSetRotations(RRCrtcPtr crtc, Rotation rotations) crtc->rotations = rotations; } +/* + * Set whether transforms are allowed on a CRTC + */ +void +RRCrtcSetTransformSupport(RRCrtcPtr crtc, Bool transforms) +{ + crtc->transforms = transforms; +} + /* * Notify the extension that the Crtc has been reconfigured, * the driver calls this whenever it has updated the mode @@ -133,7 +155,9 @@ Bool RRCrtcNotify(RRCrtcPtr crtc, RRModePtr mode, int x, - int y, Rotation rotation, int numOutputs, RROutputPtr * outputs) + int y, + Rotation rotation, + RRTransformPtr transform, int numOutputs, RROutputPtr * outputs) { int i, j; @@ -174,16 +198,24 @@ RRCrtcNotify(RRCrtcPtr crtc, if (numOutputs) { if (crtc->numOutputs) +#ifndef NXAGENT_SERVER + newoutputs = reallocarray(crtc->outputs, + numOutputs, sizeof(RROutputPtr)); +#else /* !defined(NXAGENT_SERVER) */ newoutputs = xrealloc(crtc->outputs, numOutputs * sizeof(RROutputPtr)); +#endif /* !defined(NXAGENT_SERVER) */ else +#ifndef NXAGENT_SERVER + newoutputs = xallocarray(numOutputs, sizeof(RROutputPtr)); +#else /* !defined(NXAGENT_SERVER) */ newoutputs = xalloc(numOutputs * sizeof(RROutputPtr)); +#endif /* !defined(NXAGENT_SERVER) */ if (!newoutputs) return FALSE; } else { - if (crtc->outputs) - xfree(crtc->outputs); + xfree(crtc->outputs); newoutputs = NULL; } crtc->outputs = newoutputs; @@ -216,6 +248,18 @@ RRCrtcNotify(RRCrtcPtr crtc, crtc->rotation = rotation; RRCrtcChanged(crtc, TRUE); } + if (!RRTransformEqual(transform, &crtc->client_current_transform)) { + RRTransformCopy(&crtc->client_current_transform, transform); + RRCrtcChanged(crtc, TRUE); + } + if (crtc->changed && mode) { + RRTransformCompute(x, y, + mode->mode.width, mode->mode.height, + rotation, + &crtc->client_current_transform, + &crtc->transform, &crtc->f_transform, + &crtc->f_inverse); + } return TRUE; } @@ -225,30 +269,24 @@ RRDeliverCrtcEvent(ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc) ScreenPtr pScreen = pWin->drawable.pScreen; rrScrPriv(pScreen); - xRRCrtcChangeNotifyEvent ce; RRModePtr mode = crtc->mode; - ce.type = RRNotify + RREventBase; - ce.subCode = RRNotify_CrtcChange; - ce.sequenceNumber = client->sequence; - ce.timestamp = pScrPriv->lastSetTime.milliseconds; - ce.window = pWin->drawable.id; - ce.crtc = crtc->id; - ce.rotation = crtc->rotation; - if (mode) { - ce.mode = mode->mode.id; - ce.x = crtc->x; - ce.y = crtc->y; - ce.width = mode->mode.width; - ce.height = mode->mode.height; - } - else { - ce.mode = None; - ce.x = 0; - ce.y = 0; - ce.width = 0; - ce.height = 0; - } + xRRCrtcChangeNotifyEvent ce = { + .type = RRNotify + RREventBase, + .subCode = RRNotify_CrtcChange, +#ifdef NXAGENT_SERVER + .sequenceNumber = client->sequence, +#endif + .timestamp = pScrPriv->lastSetTime.milliseconds, + .window = pWin->drawable.id, + .crtc = crtc->id, + .mode = mode ? mode->mode.id : None, + .rotation = crtc->rotation, + .x = mode ? crtc->x : 0, + .y = mode ? crtc->y : 0, + .width = mode ? mode->mode.width : 0, + .height = mode ? mode->mode.height : 0 + }; WriteEventsToClient(client, 1, (xEvent *) &ce); } @@ -269,6 +307,302 @@ RRCrtcPendingProperties(RRCrtcPtr crtc) return FALSE; } +static void +crtc_bounds(RRCrtcPtr crtc, int *left, int *right, int *top, int *bottom) +{ + *left = crtc->x; + *top = crtc->y; + + switch (crtc->rotation) { + case RR_Rotate_0: + case RR_Rotate_180: + default: + *right = crtc->x + crtc->mode->mode.width; + *bottom = crtc->y + crtc->mode->mode.height; + return; + case RR_Rotate_90: + case RR_Rotate_270: + *right = crtc->x + crtc->mode->mode.height; + *bottom = crtc->y + crtc->mode->mode.width; + return; + } +} + +/* overlapping counts as adjacent */ +static Bool +crtcs_adjacent(const RRCrtcPtr a, const RRCrtcPtr b) +{ + /* left, right, top, bottom... */ + int al, ar, at, ab; + int bl, br, bt, bb; + int cl, cr, ct, cb; /* the overlap, if any */ + + crtc_bounds(a, &al, &ar, &at, &ab); + crtc_bounds(b, &bl, &br, &bt, &bb); + + cl = max(al, bl); + cr = min(ar, br); + ct = max(at, bt); + cb = min(ab, bb); + + return (cl <= cr) && (ct <= cb); +} + +/* Depth-first search and mark all CRTCs reachable from cur */ +static void +mark_crtcs(rrScrPrivPtr pScrPriv, int *reachable, int cur) +{ + int i; + + reachable[cur] = TRUE; + for (i = 0; i < pScrPriv->numCrtcs; ++i) { + if (reachable[i] || !pScrPriv->crtcs[i]->mode) + continue; + if (crtcs_adjacent(pScrPriv->crtcs[cur], pScrPriv->crtcs[i])) + mark_crtcs(pScrPriv, reachable, i); + } +} + +static void +RRComputeContiguity(ScreenPtr pScreen) +{ + rrScrPriv(pScreen); + Bool discontiguous = TRUE; + int i, n = pScrPriv->numCrtcs; + + int *reachable = xcalloc(n, sizeof(int)); + + if (!reachable) + goto out; + + /* Find first enabled CRTC and start search for reachable CRTCs from it */ + for (i = 0; i < n; ++i) { + if (pScrPriv->crtcs[i]->mode) { + mark_crtcs(pScrPriv, reachable, i); + break; + } + } + + /* Check that all enabled CRTCs were marked as reachable */ + for (i = 0; i < n; ++i) + if (pScrPriv->crtcs[i]->mode && !reachable[i]) + goto out; + + discontiguous = FALSE; + + out: + xfree(reachable); + pScrPriv->discontiguous = discontiguous; +} + +static void +rrDestroySharedPixmap(RRCrtcPtr crtc, PixmapPtr pPixmap) { +#ifndef NXAGENT_SERVER + ScreenPtr master = crtc->pScreen->current_master; + + if (master && pPixmap->master_pixmap) { + PixmapPtr mscreenpix = master->GetScreenPixmap(master); + + master->StopPixmapTracking(mscreenpix, pPixmap); + /* + * Unref the pixmap twice: once for the original reference, and once + * for the reference implicitly added by PixmapShareToSlave. + */ + master->DestroyPixmap(pPixmap->master_pixmap); + master->DestroyPixmap(pPixmap->master_pixmap); + } +#endif + + crtc->pScreen->DestroyPixmap(pPixmap); +} + +void +RRCrtcDetachScanoutPixmap(RRCrtcPtr crtc) +{ + rrScrPriv(crtc->pScreen); + + pScrPriv->rrCrtcSetScanoutPixmap(crtc, NULL); + if (crtc->scanout_pixmap) { + rrDestroySharedPixmap(crtc, crtc->scanout_pixmap); + } + crtc->scanout_pixmap = NULL; + RRCrtcChanged(crtc, TRUE); +} + +#ifndef NXAGENT_SERVER +static PixmapPtr +rrCreateSharedPixmap(RRCrtcPtr crtc, ScreenPtr master, + int width, int height, int depth, + int x, int y, Rotation rotation) +{ + Bool ret; + PixmapPtr mpix, spix; + rrScrPriv(crtc->pScreen); + + mpix = master->CreatePixmap(master, width, height, depth, + CREATE_PIXMAP_USAGE_SHARED); + if (!mpix) + return NULL; + + spix = PixmapShareToSlave(mpix, crtc->pScreen); + if (spix == NULL) { + master->DestroyPixmap(mpix); + return NULL; + } + + ret = pScrPriv->rrCrtcSetScanoutPixmap(crtc, spix); + if (ret == FALSE) { + rrDestroySharedPixmap(crtc, spix); + ErrorF("randr: failed to set shadow slave pixmap\n"); + return NULL; + } + + return spix; +} + +static Bool +rrSetupPixmapSharing(RRCrtcPtr crtc, int width, int height, + int x, int y, Rotation rotation) +{ + ScreenPtr master = crtc->pScreen->current_master; + int depth; + PixmapPtr mscreenpix; + PixmapPtr spix; + + /* create a pixmap on the master screen, + then get a shared handle for it + create a shared pixmap on the slave screen using the handle + set the master screen to do dirty updates to the shared pixmap + from the screen pixmap. + set slave screen to scanout shared linear pixmap + */ + + mscreenpix = master->GetScreenPixmap(master); + depth = mscreenpix->drawable.depth; + + if (crtc->scanout_pixmap) + RRCrtcDetachScanoutPixmap(crtc); + + if (width == 0 && height == 0) { + return TRUE; + } + + spix = rrCreateSharedPixmap(crtc, master, + width, height, depth, + x, y, rotation); + if (spix == NULL) { + return FALSE; + } + + crtc->scanout_pixmap = spix; + + master->StartPixmapTracking(mscreenpix, spix, x, y, 0, 0, rotation); + return TRUE; +} + +static void crtc_to_box(BoxPtr box, RRCrtcPtr crtc) +{ + box->x1 = crtc->x; + box->y1 = crtc->y; + switch (crtc->rotation) { + case RR_Rotate_0: + case RR_Rotate_180: + default: + box->x2 = crtc->x + crtc->mode->mode.width; + box->y2 = crtc->y + crtc->mode->mode.height; + break; + case RR_Rotate_90: + case RR_Rotate_270: + box->x2 = crtc->x + crtc->mode->mode.height; + box->y2 = crtc->y + crtc->mode->mode.width; + break; + } +} + +static Bool +rrCheckPixmapBounding(ScreenPtr pScreen, + RRCrtcPtr rr_crtc, Rotation rotation, + int x, int y, int w, int h) +{ + RegionRec root_pixmap_region, total_region, new_crtc_region; + int c; + BoxRec newbox; + BoxPtr newsize; + ScreenPtr slave; + int new_width, new_height; + PixmapPtr screen_pixmap = pScreen->GetScreenPixmap(pScreen); + rrScrPriv(pScreen); + + PixmapRegionInit(&root_pixmap_region, screen_pixmap); + RegionInit(&total_region, NULL, 0); + + /* have to iterate all the crtcs of the attached gpu masters + and all their output slaves */ + for (c = 0; c < pScrPriv->numCrtcs; c++) { + RRCrtcPtr crtc = pScrPriv->crtcs[c]; + + if (crtc == rr_crtc) { + newbox.x1 = x; + newbox.y1 = y; + if (rotation == RR_Rotate_90 || + rotation == RR_Rotate_270) { + newbox.x2 = x + h; + newbox.y2 = y + w; + } else { + newbox.x2 = x + w; + newbox.y2 = y + h; + } + } else { + if (!crtc->mode) + continue; + crtc_to_box(&newbox, crtc); + } + RegionInit(&new_crtc_region, &newbox, 1); + RegionUnion(&total_region, &total_region, &new_crtc_region); + } + + xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) { + rrScrPrivPtr slave_priv = rrGetScrPriv(slave); + for (c = 0; c < slave_priv->numCrtcs; c++) { + RRCrtcPtr slave_crtc = slave_priv->crtcs[c]; + + if (slave_crtc == rr_crtc) { + newbox.x1 = x; + newbox.y1 = y; + if (rotation == RR_Rotate_90 || + rotation == RR_Rotate_270) { + newbox.x2 = x + h; + newbox.y2 = y + w; + } else { + newbox.x2 = x + w; + newbox.y2 = y + h; + } + } + else { + if (!slave_crtc->mode) + continue; + crtc_to_box(&newbox, slave_crtc); + } + RegionInit(&new_crtc_region, &newbox, 1); + RegionUnion(&total_region, &total_region, &new_crtc_region); + } + } + + newsize = RegionExtents(&total_region); + new_width = newsize->x2 - newsize->x1; + new_height = newsize->y2 - newsize->y1; + + if (new_width == screen_pixmap->drawable.width && + new_height == screen_pixmap->drawable.height) { + } else { + pScrPriv->rrScreenSetSize(pScreen, new_width, new_height, 0, 0); + } + + /* set shatters TODO */ + return TRUE; +} +#endif /* !defined(NXAGENT_SERVER) */ + /* * Request that the Crtc be reconfigured */ @@ -280,9 +614,20 @@ RRCrtcSet(RRCrtcPtr crtc, { ScreenPtr pScreen = crtc->pScreen; Bool ret = FALSE; + Bool recompute = TRUE; + Bool crtcChanged; + int o; rrScrPriv(pScreen); + crtcChanged = FALSE; + for (o = 0; o < numOutputs; o++) { + if (outputs[o] && outputs[o]->crtc != crtc) { + crtcChanged = TRUE; + break; + } + } + /* See if nothing changed */ if (crtc->mode == mode && crtc->x == x && @@ -290,10 +635,31 @@ RRCrtcSet(RRCrtcPtr crtc, crtc->rotation == rotation && crtc->numOutputs == numOutputs && !memcmp(crtc->outputs, outputs, numOutputs * sizeof(RROutputPtr)) && - !RRCrtcPendingProperties(crtc)) { + !RRCrtcPendingProperties(crtc) && !RRCrtcPendingTransform(crtc) && + !crtcChanged) { + recompute = FALSE; ret = TRUE; } else { +#ifndef NXAGENT_SERVER + if (pScreen->isGPU) { + ScreenPtr master = pScreen->current_master; + int width = 0, height = 0; + + if (mode) { + width = mode->mode.width; + height = mode->mode.height; + } + ret = rrCheckPixmapBounding(master, crtc, + rotation, x, y, width, height); + if (!ret) + return FALSE; + + if (pScreen->current_master) { + ret = rrSetupPixmapSharing(crtc, width, height, x, y, rotation); + } + } +#endif #if RANDR_12_INTERFACE if (pScrPriv->rrCrtcSet) { ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y, @@ -308,7 +674,7 @@ RRCrtcSet(RRCrtcPtr crtc, RRScreenRate rate; if (!mode) { - RRCrtcNotify(crtc, NULL, x, y, rotation, 0, NULL); + RRCrtcNotify(crtc, NULL, x, y, rotation, NULL, 0, NULL); ret = TRUE; } else { @@ -332,7 +698,8 @@ RRCrtcSet(RRCrtcPtr crtc, * Old 1.0 interface tied screen size to mode size */ if (ret) { - RRCrtcNotify(crtc, mode, x, y, rotation, 1, outputs); + RRCrtcNotify(crtc, mode, x, y, rotation, NULL, 1, + outputs); RRScreenSizeNotify(pScreen); } } @@ -340,7 +707,6 @@ RRCrtcSet(RRCrtcPtr crtc, #endif } if (ret) { - int o; RRTellChanged(pScreen); @@ -348,9 +714,37 @@ RRCrtcSet(RRCrtcPtr crtc, RRPostPendingProperties(outputs[o]); } } + + if (recompute) + RRComputeContiguity(pScreen); + return ret; } +/* + * Return crtc transform + */ +RRTransformPtr +RRCrtcGetTransform(RRCrtcPtr crtc) +{ + RRTransformPtr transform = &crtc->client_pending_transform; + + if (pixman_transform_is_identity(&transform->transform)) + return NULL; + return transform; +} + +/* + * Check whether the pending and current transforms are the same + */ +Bool +RRCrtcPendingTransform(RRCrtcPtr crtc) +{ + return memcmp(&crtc->client_current_transform.transform, + &crtc->client_pending_transform.transform, + sizeof(PictTransform)) != 0; +} + /* * Destroy a Crtc at shutdown */ @@ -378,9 +772,13 @@ RRCrtcDestroyResource(void *value, XID pid) break; } } + + RRResourcesChanged(pScreen); } - if (crtc->gammaRed) - xfree(crtc->gammaRed); + + if (crtc->scanout_pixmap) + RRCrtcDetachScanoutPixmap(crtc); + xfree(crtc->gammaRed); if (crtc->mode) RRModeDestroy(crtc->mode); xfree(crtc); @@ -413,6 +811,29 @@ RRCrtcGammaSet(RRCrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue) return ret; } +/* + * Request current gamma back from the DDX (if possible). + * This includes gamma size. + */ +Bool +RRCrtcGammaGet(RRCrtcPtr crtc) +{ + Bool ret = TRUE; + +#if RANDR_12_INTERFACE + ScreenPtr pScreen = crtc->pScreen; +#endif + +#if RANDR_12_INTERFACE + if (pScreen) { + rrScrPriv(pScreen); + if (pScrPriv->rrCrtcGetGamma) + ret = (*pScrPriv->rrCrtcGetGamma) (pScreen, crtc); + } +#endif + return ret; +} + /* * Notify the extension that the Crtc gamma has been changed * The driver calls this whenever it has changed the gamma values @@ -425,30 +846,35 @@ RRCrtcGammaNotify(RRCrtcPtr crtc) return TRUE; /* not much going on here */ } -/** - * Returns the width/height that the crtc scans out from the framebuffer - */ -void -RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height) +static void +RRModeGetScanoutSize(RRModePtr mode, PictTransformPtr transform, + int *width, int *height) { - if (crtc->mode == NULL) { + BoxRec box; + + if (mode == NULL) { *width = 0; *height = 0; return; } - switch (crtc->rotation & 0xf) { - case RR_Rotate_0: - case RR_Rotate_180: - *width = crtc->mode->mode.width; - *height = crtc->mode->mode.height; - break; - case RR_Rotate_90: - case RR_Rotate_270: - *width = crtc->mode->mode.height; - *height = crtc->mode->mode.width; - break; - } + box.x1 = 0; + box.y1 = 0; + box.x2 = mode->mode.width; + box.y2 = mode->mode.height; + + pixman_transform_bounds(transform, &box); + *width = box.x2 - box.x1; + *height = box.y2 - box.y1; +} + +/** + * Returns the width/height that the crtc scans out from the framebuffer + */ +void +RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height) +{ + RRModeGetScanoutSize(crtc->mode, &crtc->transform, width, height); } /* @@ -463,14 +889,17 @@ RRCrtcGammaSetSize(RRCrtcPtr crtc, int size) if (size == crtc->gammaSize) return TRUE; if (size) { +#ifndef NXAGENT_SERVER + gamma = xallocarray(size, 3 * sizeof(CARD16)); +#else /* !defined(NXAGENT_SERVER) */ gamma = xalloc(size * 3 * sizeof(CARD16)); +#endif /* !defined(NXAGENT_SERVER) */ if (!gamma) return FALSE; } else gamma = NULL; - if (crtc->gammaRed) - xfree(crtc->gammaRed); + xfree(crtc->gammaRed); crtc->gammaRed = gamma; crtc->gammaGreen = gamma + size; crtc->gammaBlue = gamma + size * 2; @@ -478,19 +907,80 @@ RRCrtcGammaSetSize(RRCrtcPtr crtc, int size) return TRUE; } +/* + * Set the pending CRTC transformation + */ + +int +RRCrtcTransformSet(RRCrtcPtr crtc, + PictTransformPtr transform, + struct pixman_f_transform *f_transform, + struct pixman_f_transform *f_inverse, + char *filter_name, + int filter_len, xFixed * params, int nparams) +{ + PictFilterPtr filter = NULL; + int width = 0, height = 0; + + if (!crtc->transforms) + return BadValue; + + if (filter_len) { + filter = PictureFindFilter(crtc->pScreen, filter_name, filter_len); + if (!filter) + return BadName; + if (filter->ValidateParams) { + if (!filter->ValidateParams(crtc->pScreen, filter->id, + params, nparams, &width, &height)) + return BadMatch; + } + else { + width = filter->width; + height = filter->height; + } + } + else { + if (nparams) + return BadMatch; + } + if (!RRTransformSetFilter(&crtc->client_pending_transform, + filter, params, nparams, width, height)) + return BadAlloc; + + crtc->client_pending_transform.transform = *transform; + crtc->client_pending_transform.f_transform = *f_transform; + crtc->client_pending_transform.f_inverse = *f_inverse; + return Success; +} + /* * Initialize crtc type */ Bool RRCrtcInit(void) { - RRCrtcType = CreateNewResourceType(RRCrtcDestroyResource); + RRCrtcType = CreateNewResourceType(RRCrtcDestroyResource +#ifndef NXAGENT_SERVER + , "CRTC" +#endif + ); if (!RRCrtcType) return FALSE; - RegisterResourceName(RRCrtcType, "CRTC"); + return TRUE; } +/* + * Initialize crtc type error value + */ +void +RRCrtcInitErrorValue(void) +{ +#ifndef NXAGENT_SERVER + SetResourceTypeErrorValue(RRCrtcType, RRErrorBase + BadRRCrtc); +#endif +} + int ProcRRGetCrtcInfo(ClientPtr client) { @@ -504,14 +994,13 @@ ProcRRGetCrtcInfo(ClientPtr client) RRModePtr mode; RROutput *outputs; RROutput *possible; - int i, j, k, n; + int i, j, k; int width, height; + BoxRec panned_area; + int n; REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq); - crtc = LookupCrtc(client, stuff->crtc, DixReadAccess); - - if (!crtc) - return RRErrorBase + BadRRCrtc; + VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); /* All crtcs must be associated with screens before client * requests are processed @@ -521,16 +1010,28 @@ ProcRRGetCrtcInfo(ClientPtr client) mode = crtc->mode; - rep.type = X_Reply; - rep.status = RRSetConfigSuccess; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.timestamp = pScrPriv->lastSetTime.milliseconds; - rep.x = crtc->x; - rep.y = crtc->y; - RRCrtcGetScanoutSize(crtc, &width, &height); - rep.width = width; - rep.height = height; + rep = (xRRGetCrtcInfoReply) { + .type = X_Reply, + .status = RRSetConfigSuccess, + .sequenceNumber = client->sequence, + .length = 0, + .timestamp = pScrPriv->lastSetTime.milliseconds + }; + if (pScrPriv->rrGetPanning && + pScrPriv->rrGetPanning(pScreen, crtc, &panned_area, NULL, NULL) && + (panned_area.x2 > panned_area.x1) && (panned_area.y2 > panned_area.y1)) { + rep.x = panned_area.x1; + rep.y = panned_area.y1; + rep.width = panned_area.x2 - panned_area.x1; + rep.height = panned_area.y2 - panned_area.y1; + } + else { + RRCrtcGetScanoutSize(crtc, &width, &height); + rep.x = crtc->x; + rep.y = crtc->y; + rep.width = width; + rep.height = height; + } rep.mode = mode ? mode->mode.id : 0; rep.rotation = crtc->rotation; rep.rotations = crtc->rotations; @@ -591,7 +1092,7 @@ ProcRRGetCrtcInfo(ClientPtr client) xfree(extra); } - return client->noClientException; + return Success; } int @@ -608,32 +1109,35 @@ ProcRRSetCrtcConfig(ClientPtr client) RROutput *outputIds; TimeStamp time; Rotation rotation; - int i, j; + int +#ifndef NXAGENT_SERVER + ret, +#endif + i, j; + CARD8 status; + int n; REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq); - numOutputs = (stuff->length - (SIZEOF(xRRSetCrtcConfigReq) >> 2)); + numOutputs = (stuff->length - bytes_to_int32(SIZEOF(xRRSetCrtcConfigReq))); + + VERIFY_RR_CRTC(stuff->crtc, crtc, DixSetAttrAccess); - crtc = LookupIDByType(stuff->crtc, RRCrtcType); - if (!crtc) { - client->errorValue = stuff->crtc; - return RRErrorBase + BadRRCrtc; - } if (stuff->mode == None) { mode = NULL; if (numOutputs > 0) return BadMatch; } else { - mode = LookupIDByType(stuff->mode, RRModeType); - if (!mode) { - client->errorValue = stuff->mode; - return RRErrorBase + BadRRMode; - } + VERIFY_RR_MODE(stuff->mode, mode, DixSetAttrAccess); if (numOutputs == 0) return BadMatch; } if (numOutputs) { +#ifndef NXAGENT_SERVER + outputs = xallocarray(numOutputs, sizeof(RROutputPtr)); +#else /* !defined(NXAGENT_SERVER) */ outputs = xalloc(numOutputs * sizeof(RROutputPtr)); +#endif /* !defined(NXAGENT_SERVER) */ if (!outputs) return BadAlloc; } @@ -642,6 +1146,15 @@ ProcRRSetCrtcConfig(ClientPtr client) outputIds = (RROutput *) (stuff + 1); for (i = 0; i < numOutputs; i++) { +#ifndef NXAGENT_SERVER + ret = dixLookupResourceByType((void **) (outputs + i), outputIds[i], + RROutputType, client, DixSetAttrAccess); + + if (ret != Success) { + xfree(outputs); + return ret; + } +#else /* !defined(NXAGENT_SERVER) */ outputs[i] = (RROutputPtr) LookupIDByType(outputIds[i], RROutputType); if (!outputs[i]) { client->errorValue = outputIds[i]; @@ -649,13 +1162,13 @@ ProcRRSetCrtcConfig(ClientPtr client) xfree(outputs); return RRErrorBase + BadRROutput; } +#endif /* !defined(NXAGENT_SERVER) */ /* validate crtc for this output */ for (j = 0; j < outputs[i]->numCrtcs; j++) if (outputs[i]->crtcs[j] == crtc) break; if (j == outputs[i]->numCrtcs) { - if (outputs) - xfree(outputs); + xfree(outputs); return BadMatch; } /* validate mode for this output */ @@ -667,8 +1180,7 @@ ProcRRSetCrtcConfig(ClientPtr client) break; } if (j == outputs[i]->numModes + outputs[i]->numUserModes) { - if (outputs) - xfree(outputs); + xfree(outputs); return BadMatch; } } @@ -684,8 +1196,7 @@ ProcRRSetCrtcConfig(ClientPtr client) break; } if (k == outputs[i]->numClones) { - if (outputs) - xfree(outputs); + xfree(outputs); return BadMatch; } } @@ -698,7 +1209,7 @@ ProcRRSetCrtcConfig(ClientPtr client) if (!pScrPriv) { time = currentTime; - rep.status = RRSetConfigFailed; + status = RRSetConfigFailed; goto sendReply; } @@ -719,8 +1230,7 @@ ProcRRSetCrtcConfig(ClientPtr client) * Invalid rotation */ client->errorValue = stuff->rotation; - if (outputs) - xfree(outputs); + xfree(outputs); return BadValue; } @@ -730,8 +1240,7 @@ ProcRRSetCrtcConfig(ClientPtr client) * requested rotation or reflection not supported by screen */ client->errorValue = stuff->rotation; - if (outputs) - xfree(outputs); + xfree(outputs); return BadMatch; } @@ -739,71 +1248,220 @@ ProcRRSetCrtcConfig(ClientPtr client) /* * Check screen size bounds if the DDX provides a 1.2 interface * for setting screen size. Else, assume the CrtcSet sets - * the size along with the mode + * the size along with the mode. If the driver supports transforms, + * then it must allow crtcs to display a subset of the screen, so + * only do this check for drivers without transform support. */ - if (pScrPriv->rrScreenSetSize) { - int source_width = mode->mode.width; - int source_height = mode->mode.height; - - if ((rotation & 0xf) == RR_Rotate_90 || - (rotation & 0xf) == RR_Rotate_270) { - source_width = mode->mode.height; - source_height = mode->mode.width; + if (pScrPriv->rrScreenSetSize && !crtc->transforms) { + int source_width; + int source_height; + PictTransform transform; + struct pixman_f_transform f_transform, f_inverse; + int width, height; + +#ifndef NXAGENT_SERVER + if (pScreen->isGPU) { + width = pScreen->current_master->width; + height = pScreen->current_master->height; } - if (stuff->x + source_width > pScreen->width) { + else +#else /* !defined(NXAGENT_SERVER) */ + { + width = pScreen->width; + height = pScreen->height; + } +#endif /* !defined(NXAGENT_SERVER) */ + + RRTransformCompute(stuff->x, stuff->y, + mode->mode.width, mode->mode.height, + rotation, + &crtc->client_pending_transform, + &transform, &f_transform, &f_inverse); + + RRModeGetScanoutSize(mode, &transform, &source_width, + &source_height); + if (stuff->x + source_width > width) { client->errorValue = stuff->x; - if (outputs) - xfree(outputs); + xfree(outputs); return BadValue; } - if (stuff->y + source_height > pScreen->height) { + if (stuff->y + source_height > height) { client->errorValue = stuff->y; - if (outputs) - xfree(outputs); + xfree(outputs); return BadValue; } } #endif } - /* - * Make sure the requested set-time is not older than - * the last set-time - */ - if (CompareTimeStamps(time, pScrPriv->lastSetTime) < 0) { - rep.status = RRSetConfigInvalidTime; - goto sendReply; - } - if (!RRCrtcSet(crtc, mode, stuff->x, stuff->y, rotation, numOutputs, outputs)) { - rep.status = RRSetConfigFailed; + status = RRSetConfigFailed; goto sendReply; } - rep.status = RRSetConfigSuccess; + status = RRSetConfigSuccess; pScrPriv->lastSetTime = time; sendReply: - if (outputs) - xfree(outputs); + xfree(outputs); + + rep = (xRRSetCrtcConfigReply) { + .type = X_Reply, + .status = status, + .sequenceNumber = client->sequence, + .length = 0, + .newTimestamp = pScrPriv->lastSetTime.milliseconds + }; + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.newTimestamp, n); + } + WriteToClient(client, sizeof(xRRSetCrtcConfigReply), (char *) &rep); - rep.type = X_Reply; - /* rep.status has already been filled in */ - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.newTimestamp = pScrPriv->lastSetTime.milliseconds; + return Success; +} + +int +ProcRRGetPanning(ClientPtr client) +{ + REQUEST(xRRGetPanningReq); + xRRGetPanningReply rep; + RRCrtcPtr crtc; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + BoxRec total; + BoxRec tracking; + INT16 border[4]; + int n; + + REQUEST_SIZE_MATCH(xRRGetPanningReq); + VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); + + /* All crtcs must be associated with screens before client + * requests are processed + */ + pScreen = crtc->pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + if (!pScrPriv) + return RRErrorBase + BadRRCrtc; + + rep = (xRRGetPanningReply) { + .type = X_Reply, + .status = RRSetConfigSuccess, + .sequenceNumber = client->sequence, + .length = 1, + .timestamp = pScrPriv->lastSetTime.milliseconds + }; + if (pScrPriv->rrGetPanning && + pScrPriv->rrGetPanning(pScreen, crtc, &total, &tracking, border)) { + rep.left = total.x1; + rep.top = total.y1; + rep.width = total.x2 - total.x1; + rep.height = total.y2 - total.y1; + rep.track_left = tracking.x1; + rep.track_top = tracking.y1; + rep.track_width = tracking.x2 - tracking.x1; + rep.track_height = tracking.y2 - tracking.y1; + rep.border_left = border[0]; + rep.border_top = border[1]; + rep.border_right = border[2]; + rep.border_bottom = border[3]; + } if (client->swapped) { - int n; + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.timestamp, n); + swaps(&rep.left, n); + swaps(&rep.top, n); + swaps(&rep.width, n); + swaps(&rep.height, n); + swaps(&rep.track_left, n); + swaps(&rep.track_top, n); + swaps(&rep.track_width, n); + swaps(&rep.track_height, n); + swaps(&rep.border_left, n); + swaps(&rep.border_top, n); + swaps(&rep.border_right, n); + swaps(&rep.border_bottom, n); + } + WriteToClient(client, sizeof(xRRGetPanningReply), (char *) &rep); + return Success; +} + +int +ProcRRSetPanning(ClientPtr client) +{ + REQUEST(xRRSetPanningReq); + xRRSetPanningReply rep; + RRCrtcPtr crtc; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + TimeStamp time; + BoxRec total; + BoxRec tracking; + INT16 border[4]; + CARD8 status; + int n; + + REQUEST_SIZE_MATCH(xRRSetPanningReq); + VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); + + /* All crtcs must be associated with screens before client + * requests are processed + */ + pScreen = crtc->pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + if (!pScrPriv) { + time = currentTime; + status = RRSetConfigFailed; + goto sendReply; + } + + time = ClientTimeToServerTime(stuff->timestamp); + + if (!pScrPriv->rrGetPanning) + return RRErrorBase + BadRRCrtc; + + total.x1 = stuff->left; + total.y1 = stuff->top; + total.x2 = total.x1 + stuff->width; + total.y2 = total.y1 + stuff->height; + tracking.x1 = stuff->track_left; + tracking.y1 = stuff->track_top; + tracking.x2 = tracking.x1 + stuff->track_width; + tracking.y2 = tracking.y1 + stuff->track_height; + border[0] = stuff->border_left; + border[1] = stuff->border_top; + border[2] = stuff->border_right; + border[3] = stuff->border_bottom; + + if (!pScrPriv->rrSetPanning(pScreen, crtc, &total, &tracking, border)) + return BadMatch; + + pScrPriv->lastSetTime = time; + status = RRSetConfigSuccess; + + sendReply: + rep = (xRRSetPanningReply) { + .type = X_Reply, + .status = status, + .sequenceNumber = client->sequence, + .length = 0, + .newTimestamp = pScrPriv->lastSetTime.milliseconds + }; + if (client->swapped) { swaps(&rep.sequenceNumber, n); swapl(&rep.length, n); swapl(&rep.newTimestamp, n); } - WriteToClient(client, sizeof(xRRSetCrtcConfigReply), (char *) &rep); - - return client->noClientException; + WriteToClient(client, sizeof(xRRSetPanningReply), (char *) &rep); + return Success; } int @@ -815,21 +1473,25 @@ ProcRRGetCrtcGammaSize(ClientPtr client) int n; REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq); - crtc = LookupCrtc(client, stuff->crtc, DixReadAccess); - if (!crtc) + VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); + + /* Gamma retrieval failed, any better error? */ + if (!RRCrtcGammaGet(crtc)) return RRErrorBase + BadRRCrtc; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - reply.length = 0; - reply.size = crtc->gammaSize; + reply = (xRRGetCrtcGammaSizeReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0, + .size = crtc->gammaSize + }; if (client->swapped) { swaps(&reply.sequenceNumber, n); swapl(&reply.length, n); swaps(&reply.size, n); } WriteToClient(client, sizeof(xRRGetCrtcGammaSizeReply), (char *) &reply); - return client->noClientException; + return Success; } int @@ -838,13 +1500,15 @@ ProcRRGetCrtcGamma(ClientPtr client) REQUEST(xRRGetCrtcGammaReq); xRRGetCrtcGammaReply reply; RRCrtcPtr crtc; - int n; unsigned long len; - char *extra; + char *extra = NULL; + int n; REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq); - crtc = LookupCrtc(client, stuff->crtc, DixReadAccess); - if (!crtc) + VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); + + /* Gamma retrieval failed, any better error? */ + if (!RRCrtcGammaGet(crtc)) return RRErrorBase + BadRRCrtc; len = crtc->gammaSize * 3 * 2; @@ -855,10 +1519,12 @@ ProcRRGetCrtcGamma(ClientPtr client) return BadAlloc; } - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - reply.length = (len + 3) >> 2; - reply.size = crtc->gammaSize; + reply = (xRRGetCrtcGammaReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = bytes_to_int32(len), + .size = crtc->gammaSize + }; if (client->swapped) { swaps(&reply.sequenceNumber, n); swapl(&reply.length, n); @@ -871,7 +1537,7 @@ ProcRRGetCrtcGamma(ClientPtr client) WriteSwappedDataToClient(client, len, extra); xfree(extra); } - return client->noClientException; + return Success; } int @@ -883,11 +1549,9 @@ ProcRRSetCrtcGamma(ClientPtr client) CARD16 *red, *green, *blue; REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq); - crtc = LookupCrtc(client, stuff->crtc, DixWriteAccess); - if (!crtc) - return RRErrorBase + BadRRCrtc; + VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); - len = client->req_len - (sizeof(xRRSetCrtcGammaReq) >> 2); + len = client->req_len - bytes_to_int32(sizeof(xRRSetCrtcGammaReq)); if (len < (stuff->size * 3 + 1) >> 1) return BadLength; @@ -902,3 +1566,335 @@ ProcRRSetCrtcGamma(ClientPtr client) return Success; } + +/* Version 1.3 additions */ + +int +ProcRRSetCrtcTransform(ClientPtr client) +{ + REQUEST(xRRSetCrtcTransformReq); + RRCrtcPtr crtc; + PictTransform transform; + struct pixman_f_transform f_transform, f_inverse; + char *filter; + int nbytes; + xFixed *params; + int nparams; + + REQUEST_AT_LEAST_SIZE(xRRSetCrtcTransformReq); + VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); + + PictTransform_from_xRenderTransform(&transform, &stuff->transform); + pixman_f_transform_from_pixman_transform(&f_transform, &transform); + if (!pixman_f_transform_invert(&f_inverse, &f_transform)) + return BadMatch; + + filter = (char *) (stuff + 1); + nbytes = stuff->nbytesFilter; + params = (xFixed *) (filter + pad_to_int32(nbytes)); + nparams = ((xFixed *) stuff + client->req_len) - params; + if (nparams < 0) + return BadLength; + + return RRCrtcTransformSet(crtc, &transform, &f_transform, &f_inverse, + filter, nbytes, params, nparams); +} + +#define CrtcTransformExtra (SIZEOF(xRRGetCrtcTransformReply) - 32) + +static int +transform_filter_length(RRTransformPtr transform) +{ + int nbytes, nparams; + + if (transform->filter == NULL) + return 0; + nbytes = strlen(transform->filter->name); + nparams = transform->nparams; + return pad_to_int32(nbytes) + (nparams * sizeof(xFixed)); +} + +static int +transform_filter_encode(ClientPtr client, char *output, + CARD16 *nbytesFilter, + CARD16 *nparamsFilter, RRTransformPtr transform) +{ + int nbytes, nparams; + int n; + + if (transform->filter == NULL) { + *nbytesFilter = 0; + *nparamsFilter = 0; + return 0; + } + nbytes = strlen(transform->filter->name); + nparams = transform->nparams; + *nbytesFilter = nbytes; + *nparamsFilter = nparams; + memcpy(output, transform->filter->name, nbytes); + while ((nbytes & 3) != 0) + output[nbytes++] = 0; + memcpy(output + nbytes, transform->params, nparams * sizeof(xFixed)); + if (client->swapped) { + swaps(nbytesFilter, n); + swaps(nparamsFilter, n); + SwapLongs((CARD32 *) (output + nbytes), nparams); + } + nbytes += nparams * sizeof(xFixed); + return nbytes; +} + +static void +transform_encode(ClientPtr client, xRenderTransform * wire, + PictTransform * pict) +{ + xRenderTransform_from_PictTransform(wire, pict); + if (client->swapped) + SwapLongs((CARD32 *) wire, bytes_to_int32(sizeof(xRenderTransform))); +} + +int +ProcRRGetCrtcTransform(ClientPtr client) +{ + REQUEST(xRRGetCrtcTransformReq); + xRRGetCrtcTransformReply *reply; + RRCrtcPtr crtc; + int nextra; + RRTransformPtr current, pending; + char *extra; + int n; + + REQUEST_SIZE_MATCH(xRRGetCrtcTransformReq); + VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); + + pending = &crtc->client_pending_transform; + current = &crtc->client_current_transform; + + nextra = (transform_filter_length(pending) + + transform_filter_length(current)); + + reply = xcalloc(1, sizeof(xRRGetCrtcTransformReply) + nextra); + if (!reply) + return BadAlloc; + + extra = (char *) (reply + 1); + reply->type = X_Reply; + reply->sequenceNumber = client->sequence; + reply->length = bytes_to_int32(CrtcTransformExtra + nextra); + + reply->hasTransforms = crtc->transforms; + + transform_encode(client, &reply->pendingTransform, &pending->transform); + extra += transform_filter_encode(client, extra, + &reply->pendingNbytesFilter, + &reply->pendingNparamsFilter, pending); + + transform_encode(client, &reply->currentTransform, ¤t->transform); + extra += transform_filter_encode(client, extra, + &reply->currentNbytesFilter, + &reply->currentNparamsFilter, current); + + if (client->swapped) { + swaps(&reply->sequenceNumber, n); + swapl(&reply->length, n); + } + WriteToClient(client, sizeof(xRRGetCrtcTransformReply) + nextra, + (char *) reply); + xfree(reply); + return Success; +} + +static Bool +check_all_screen_crtcs(ScreenPtr pScreen, int *x, int *y) +{ + rrScrPriv(pScreen); + int i; + for (i = 0; i < pScrPriv->numCrtcs; i++) { + RRCrtcPtr crtc = pScrPriv->crtcs[i]; + + int left, right, top, bottom; + + if (!crtc->mode) + continue; + + crtc_bounds(crtc, &left, &right, &top, &bottom); + + if ((*x >= left) && (*x < right) && (*y >= top) && (*y < bottom)) + return TRUE; + } + return FALSE; +} + +static Bool +constrain_all_screen_crtcs( +#ifndef NXAGENT_SERVER + DeviceIntPtr pDev, +#endif /* !defined(NXAGENT_SERVER) */ + ScreenPtr pScreen, int *x, int *y) +{ + rrScrPriv(pScreen); + int i; + + /* if we're trying to escape, clamp to the CRTC we're coming from */ + for (i = 0; i < pScrPriv->numCrtcs; i++) { + RRCrtcPtr crtc = pScrPriv->crtcs[i]; + int nx, ny; + int left, right, top, bottom; + + if (!crtc->mode) + continue; + + crtc_bounds(crtc, &left, &right, &top, &bottom); +#ifndef NXAGENT_SERVER + miPointerGetPosition(pDev, &nx, &ny); +#else /* !defined(NXAGENT_SERVER) */ + + miPointerPosition(&nx, &ny); +#endif /* !defined(NXAGENT_SERVER) */ + + if ((nx >= left) && (nx < right) && (ny >= top) && (ny < bottom)) { + if (*x < left) + *x = left; + if (*x >= right) + *x = right - 1; + if (*y < top) + *y = top; + if (*y >= bottom) + *y = bottom - 1; + + return TRUE; + } + } + return FALSE; +} + +void +RRConstrainCursorHarder( +#ifndef NXAGENT_SERVER + DeviceIntPtr pDev, +#endif /* !defined(NXAGENT_SERVER) */ + ScreenPtr pScreen, int mode, int *x, + int *y) +{ + rrScrPriv(pScreen); + Bool ret; +#ifndef NXAGENT_SERVER + ScreenPtr slave; +#endif + + /* intentional dead space -> let it float */ + if (pScrPriv->discontiguous) + return; + + /* if we're moving inside a crtc, we're fine */ + ret = check_all_screen_crtcs(pScreen, x, y); + if (ret == TRUE) + return; + +#ifndef NXAGENT_SERVER + xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) { + ret = check_all_screen_crtcs(slave, x, y); + if (ret == TRUE) + return; + } +#endif /* !defined(NXAGENT_SERVER) */ + + /* if we're trying to escape, clamp to the CRTC we're coming from */ + ret = constrain_all_screen_crtcs( +#ifndef NXAGENT_SERVER + pDev, +#endif /* !defined(NXAGENT_SERVER) */ + pScreen, x, y); + if (ret == TRUE) + return; + +#ifndef NXAGENT_SERVER + xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) { + ret = constrain_all_screen_crtcs(pDev, slave, x, y); + if (ret == TRUE) + return; + } +#endif /* !defined(NXAGENT_SERVER) */ +} + +Bool +RRReplaceScanoutPixmap(DrawablePtr pDrawable, PixmapPtr pPixmap, Bool enable) +{ + rrScrPriv(pDrawable->pScreen); + Bool ret = TRUE; + PixmapPtr *saved_scanout_pixmap; + int i; + + saved_scanout_pixmap = xalloc(sizeof(PixmapPtr) * pScrPriv->numCrtcs); + if (saved_scanout_pixmap == NULL) + return FALSE; + + for (i = 0; i < pScrPriv->numCrtcs; i++) { + RRCrtcPtr crtc = pScrPriv->crtcs[i]; + Bool size_fits; + + saved_scanout_pixmap[i] = crtc->scanout_pixmap; + + if (!crtc->mode && enable) + continue; + if (!crtc->scanout_pixmap && !enable) + continue; + + size_fits = (crtc->mode && + crtc->x == pDrawable->x && + crtc->y == pDrawable->y && + crtc->mode->mode.width == pDrawable->width && + crtc->mode->mode.height == pDrawable->height); + + /* is the pixmap already set? */ + if (crtc->scanout_pixmap == pPixmap) { + /* if its a disable then don't care about size */ + if (enable == FALSE) { + /* set scanout to NULL */ + crtc->scanout_pixmap = NULL; + } + else if (!size_fits) { + /* if the size no longer fits then drop off */ + crtc->scanout_pixmap = NULL; + pScrPriv->rrCrtcSetScanoutPixmap(crtc, crtc->scanout_pixmap); + + (*pScrPriv->rrCrtcSet) (pDrawable->pScreen, crtc, crtc->mode, crtc->x, crtc->y, + crtc->rotation, crtc->numOutputs, crtc->outputs); + saved_scanout_pixmap[i] = crtc->scanout_pixmap; + ret = FALSE; + } + else { + /* if the size fits then we are already setup */ + } + } + else { + if (!size_fits) + ret = FALSE; + else if (enable) + crtc->scanout_pixmap = pPixmap; + else + /* reject an attempt to disable someone else's scanout_pixmap */ + ret = FALSE; + } + } + + for (i = 0; i < pScrPriv->numCrtcs; i++) { + RRCrtcPtr crtc = pScrPriv->crtcs[i]; + + if (crtc->scanout_pixmap == saved_scanout_pixmap[i]) + continue; + + if (ret) { + pScrPriv->rrCrtcSetScanoutPixmap(crtc, crtc->scanout_pixmap); + + (*pScrPriv->rrCrtcSet) (pDrawable->pScreen, crtc, crtc->mode, + crtc->x, crtc->y, crtc->rotation, + crtc->numOutputs, crtc->outputs); + } + else + crtc->scanout_pixmap = saved_scanout_pixmap[i]; + } + xfree(saved_scanout_pixmap); + + return ret; +} diff --git a/nx-X11/programs/Xserver/randr/rrdispatch.c b/nx-X11/programs/Xserver/randr/rrdispatch.c index a8fa6965f..a8ca35d16 100644 --- a/nx-X11/programs/Xserver/randr/rrdispatch.c +++ b/nx-X11/programs/Xserver/randr/rrdispatch.c @@ -21,48 +21,62 @@ */ #include "randrstr.h" - -#define SERVER_RANDR_MAJOR 1 -#define SERVER_RANDR_MINOR 2 +#ifndef NXAGENT_SERVER +#include "protocol-versions.h" +#else +#define SERVER_RANDR_MAJOR_VERSION 1 +#define SERVER_RANDR_MINOR_VERSION 5 +#endif Bool RRClientKnowsRates(ClientPtr pClient) { rrClientPriv(pClient); - return (pRRClient->major_version > 1 || - (pRRClient->major_version == 1 && pRRClient->minor_version >= 1)); + return version_compare(pRRClient->major_version, pRRClient->minor_version, + 1, 1) >= 0; } static int ProcRRQueryVersion(ClientPtr client) { - xRRQueryVersionReply rep; - register int n; + int n; + xRRQueryVersionReply rep = { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0 + }; REQUEST(xRRQueryVersionReq); rrClientPriv(client); REQUEST_SIZE_MATCH(xRRQueryVersionReq); pRRClient->major_version = stuff->majorVersion; pRRClient->minor_version = stuff->minorVersion; - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - /* - * Report the current version; the current - * spec says they're all compatible after 1.0 - */ - rep.majorVersion = SERVER_RANDR_MAJOR; - rep.minorVersion = SERVER_RANDR_MINOR; + + if (version_compare(stuff->majorVersion, stuff->minorVersion, + SERVER_RANDR_MAJOR_VERSION, + SERVER_RANDR_MINOR_VERSION) < 0) { + rep.majorVersion = stuff->majorVersion; + rep.minorVersion = stuff->minorVersion; + } + else { + rep.majorVersion = SERVER_RANDR_MAJOR_VERSION; + rep.minorVersion = SERVER_RANDR_MINOR_VERSION; + } + if (client->swapped) { swaps(&rep.sequenceNumber, n); swapl(&rep.length, n); swapl(&rep.majorVersion, n); swapl(&rep.minorVersion, n); } +#ifndef NXAGENT_SERVER + WriteToClient(client, sizeof(xRRQueryVersionReply), &rep); +#else WriteToClient(client, sizeof(xRRQueryVersionReply), (char *) &rep); - return (client->noClientException); +#endif + return Success; } static int @@ -78,19 +92,30 @@ ProcRRSelectInput(ClientPtr client) REQUEST_SIZE_MATCH(xRRSelectInputReq); #ifndef NXAGENT_SERVER - rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess); + rc = dixLookupWindow(&pWin, stuff->window, client, DixReceiveAccess); #else pWin = SecurityLookupWindow(stuff->window, client, SecurityWriteAccess); rc = pWin ? Success : BadWindow; #endif if (rc != Success) return rc; - pHead = (RREventPtr *) SecurityLookupIDByType(client, - pWin->drawable.id, - RREventType, DixWriteAccess); +#ifndef NXAGENT_SERVER + rc = dixLookupResourceByType((void **) &pHead, pWin->drawable.id, + RREventType, client, DixWriteAccess); +#else /* !defined(NXAGENT_SERVER) */ + pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, RREventType); +#endif /* !defined(NXAGENT_SERVER) */ + + if (rc != Success && rc != BadValue) + return rc; if (stuff->enable & (RRScreenChangeNotifyMask | - RRCrtcChangeNotifyMask | RROutputChangeNotifyMask)) { + RRCrtcChangeNotifyMask | + RROutputChangeNotifyMask | + RROutputPropertyNotifyMask | + RRProviderChangeNotifyMask | + RRProviderPropertyNotifyMask | + RRResourceChangeNotifyMask)) { ScreenPtr pScreen = pWin->drawable.pScreen; rrScrPriv(pScreen); @@ -142,13 +167,37 @@ ProcRRSelectInput(ClientPtr client) /* * Now see if the client needs an event */ - if (pScrPriv && (pRREvent->mask & RRScreenChangeNotifyMask)) { + if (pScrPriv) { pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum]; if (CompareTimeStamps(pTimes->setTime, pScrPriv->lastSetTime) != 0 || CompareTimeStamps(pTimes->configTime, pScrPriv->lastConfigTime) != 0) { - RRDeliverScreenEvent(client, pWin, pScreen); + if (pRREvent->mask & RRScreenChangeNotifyMask) { + RRDeliverScreenEvent(client, pWin, pScreen); + } + + if (pRREvent->mask & RRCrtcChangeNotifyMask) { + int i; + + for (i = 0; i < pScrPriv->numCrtcs; i++) { + RRDeliverCrtcEvent(client, pWin, pScrPriv->crtcs[i]); + } + } + + if (pRREvent->mask & RROutputChangeNotifyMask) { + int i; + + for (i = 0; i < pScrPriv->numOutputs; i++) { + RRDeliverOutputEvent(client, pWin, + pScrPriv->outputs[i]); + } + } + + /* We don't check for RROutputPropertyNotifyMask, as randrproto.txt doesn't + * say if there ought to be notifications of changes to output properties + * if those changes occurred before the time RRSelectInput is called. + */ } } } @@ -209,4 +258,26 @@ int (*ProcRandrVector[RRNumberRequests]) (ClientPtr) = { ProcRRGetCrtcGammaSize, /* 22 */ ProcRRGetCrtcGamma, /* 23 */ ProcRRSetCrtcGamma, /* 24 */ +/* V1.3 additions */ + ProcRRGetScreenResourcesCurrent, /* 25 */ + ProcRRSetCrtcTransform, /* 26 */ + ProcRRGetCrtcTransform, /* 27 */ + ProcRRGetPanning, /* 28 */ + ProcRRSetPanning, /* 29 */ + ProcRRSetOutputPrimary, /* 30 */ + ProcRRGetOutputPrimary, /* 31 */ +/* V1.4 additions */ + ProcRRGetProviders, /* 32 */ + ProcRRGetProviderInfo, /* 33 */ + ProcRRSetProviderOffloadSink, /* 34 */ + ProcRRSetProviderOutputSource, /* 35 */ + ProcRRListProviderProperties, /* 36 */ + ProcRRQueryProviderProperty, /* 37 */ + ProcRRConfigureProviderProperty, /* 38 */ + ProcRRChangeProviderProperty, /* 39 */ + ProcRRDeleteProviderProperty, /* 40 */ + ProcRRGetProviderProperty, /* 41 */ + ProcRRGetMonitors, /* 42 */ + ProcRRSetMonitor, /* 43 */ + ProcRRDeleteMonitor, /* 44 */ }; diff --git a/nx-X11/programs/Xserver/randr/rrinfo.c b/nx-X11/programs/Xserver/randr/rrinfo.c index 070f5ca0c..df9b79986 100644 --- a/nx-X11/programs/Xserver/randr/rrinfo.c +++ b/nx-X11/programs/Xserver/randr/rrinfo.c @@ -36,7 +36,7 @@ RROldModeAdd(RROutputPtr output, RRScreenSizePtr size, int refresh) RRModePtr *modes; memset(&modeInfo, '\0', sizeof(modeInfo)); - sprintf(name, "%dx%d", size->width, size->height); + snprintf(name, sizeof(name), "%dx%d", size->width, size->height); modeInfo.width = size->width; modeInfo.height = size->height; @@ -55,8 +55,13 @@ RROldModeAdd(RROutputPtr output, RRScreenSizePtr size, int refresh) } if (output->numModes) +#ifndef NXAGENT_SERVER + modes = reallocarray(output->modes, + output->numModes + 1, sizeof(RRModePtr)); +#else /* !defined(NXAGENT_SERVER) */ modes = xrealloc(output->modes, (output->numModes + 1) * sizeof(RRModePtr)); +#endif /* !defined(NXAGENT_SERVER) */ else modes = xalloc(sizeof(RRModePtr)); if (!modes) { @@ -97,9 +102,7 @@ RRScanOldConfig(ScreenPtr pScreen, Rotation rotations) return; RROutputSetCrtcs(output, &crtc, 1); RROutputSetConnection(output, RR_Connected); -#ifdef RENDER RROutputSetSubpixelOrder(output, PictureGetSubpixelOrder(pScreen)); -#endif } output = pScrPriv->outputs[0]; @@ -145,7 +148,8 @@ RRScanOldConfig(ScreenPtr pScreen, Rotation rotations) /* find size bounds */ for (i = 0; i < output->numModes + output->numUserModes; i++) { mode = (i < output->numModes ? - output->modes[i] : output->userModes[i - output->numModes]); + output->modes[i] : + output->userModes[i - output->numModes]); width = mode->mode.width; height = mode->mode.height; @@ -163,7 +167,7 @@ RRScanOldConfig(ScreenPtr pScreen, Rotation rotations) /* notice current mode */ if (newMode) - RRCrtcNotify(crtc, newMode, 0, 0, pScrPriv->rotation, 1, &output); + RRCrtcNotify(crtc, newMode, 0, 0, pScrPriv->rotation, NULL, 1, &output); } #endif @@ -171,12 +175,20 @@ RRScanOldConfig(ScreenPtr pScreen, Rotation rotations) * Poll the driver for changed information */ Bool -RRGetInfo(ScreenPtr pScreen) +RRGetInfo(ScreenPtr pScreen, Bool force_query) { rrScrPriv(pScreen); Rotation rotations; int i; + /* Return immediately if we don't need to re-query and we already have the + * information. + */ + if (!force_query) { + if (pScrPriv->numCrtcs != 0 || pScrPriv->numOutputs != 0) + return TRUE; + } + for (i = 0; i < pScrPriv->numOutputs; i++) pScrPriv->outputs[i]->changed = FALSE; for (i = 0; i < pScrPriv->numCrtcs; i++) @@ -218,7 +230,7 @@ RRScreenSetSizeRange(ScreenPtr pScreen, pScrPriv->minHeight = minHeight; pScrPriv->maxWidth = maxWidth; pScrPriv->maxHeight = maxHeight; - pScrPriv->changed = TRUE; + RRSetChanged(pScreen); pScrPriv->configChanged = TRUE; } @@ -259,8 +271,13 @@ RRRegisterSize(ScreenPtr pScreen, for (i = 0; i < pScrPriv->nSizes; i++) if (RRScreenSizeMatches(&tmp, &pScrPriv->pSizes[i])) return &pScrPriv->pSizes[i]; +#ifndef NXAGENT_SERVER + pNew = reallocarray(pScrPriv->pSizes, + pScrPriv->nSizes + 1, sizeof(RRScreenSize)); +#else /* !defined(NXAGENT_SERVER) */ pNew = xrealloc(pScrPriv->pSizes, (pScrPriv->nSizes + 1) * sizeof(RRScreenSize)); +#endif /* !defined(NXAGENT_SERVER) */ if (!pNew) return 0; pNew[pScrPriv->nSizes++] = tmp; @@ -282,7 +299,11 @@ RRRegisterRate(ScreenPtr pScreen, RRScreenSizePtr pSize, int rate) if (pSize->pRates[i].rate == rate) return TRUE; +#ifndef NXAGENT_SERVER + pNew = reallocarray(pSize->pRates, pSize->nRates + 1, sizeof(RRScreenRate)); +#else /* !defined(NXAGENT_SERVER) */ pNew = xrealloc(pSize->pRates, (pSize->nRates + 1) * sizeof(RRScreenRate)); +#endif /* !defined(NXAGENT_SERVER) */ if (!pNew) return FALSE; pRate = &pNew[pSize->nRates++]; diff --git a/nx-X11/programs/Xserver/randr/rrmode.c b/nx-X11/programs/Xserver/randr/rrmode.c index 4fe116400..918e0f221 100644 --- a/nx-X11/programs/Xserver/randr/rrmode.c +++ b/nx-X11/programs/Xserver/randr/rrmode.c @@ -38,7 +38,6 @@ /**************************************************************************/ #include "randrstr.h" -#include "registry.h" RESTYPE RRModeType; @@ -97,7 +96,12 @@ RRModeCreate(xRRModeInfo * modeInfo, const char *name, ScreenPtr userScreen) mode->userScreen = userScreen; if (num_modes) +#ifndef NXAGENT_SERVER + newModes = reallocarray(modes, num_modes + 1, sizeof(RRModePtr)); +#else /* !defined(NXAGENT_SERVER) */ newModes = xrealloc(modes, (num_modes + 1) * sizeof(RRModePtr)); +#endif /* !defined(NXAGENT_SERVER) */ + else newModes = xalloc(sizeof(RRModePtr)); @@ -113,6 +117,7 @@ RRModeCreate(xRRModeInfo * modeInfo, const char *name, ScreenPtr userScreen) } modes = newModes; modes[num_modes++] = mode; + /* * give the caller a reference to this mode */ @@ -203,7 +208,11 @@ RRModesForScreen(ScreenPtr pScreen, int *num_ret) RRModePtr *screen_modes; int num_screen_modes = 0; +#ifndef NXAGENT_SERVER + screen_modes = xallocarray((num_modes ? num_modes : 1), sizeof(RRModePtr)); +#else /* !defined(NXAGENT_SERVER) */ screen_modes = xalloc((num_modes ? num_modes : 1) * sizeof(RRModePtr)); +#endif /* !defined(NXAGENT_SERVER) */ if (!screen_modes) return NULL; @@ -268,13 +277,8 @@ RRModeDestroy(RRModePtr mode) { int m; - if (--mode->refcnt > 0) { -#ifdef DEBUG - fprintf(stderr, "RRModeDestroy: mode [%s] ([%p]) refcnt [%d -> %d]\n", - mode->name, mode, mode->refcnt + 1, mode->refcnt); -#endif + if (--mode->refcnt > 0) return; - } for (m = 0; m < num_modes; m++) { if (modes[m] == mode) { memmove(modes + m, modes + m + 1, @@ -288,37 +292,46 @@ RRModeDestroy(RRModePtr mode) } } -#ifdef DEBUG - fprintf(stderr, "RRModeDestroy: destroyed mode [%s] ([%p])\n", mode->name, - mode); -#endif xfree(mode); } static int RRModeDestroyResource(void *value, XID pid) { -#ifdef DEBUG - fprintf(stderr, "RRModeDestroyResource: mode [%s] ([%p]) refcnt [%d]\n", - ((RRModePtr) value)->name, (RRModePtr) value, - ((RRModePtr) value)->refcnt); -#endif RRModeDestroy((RRModePtr) value); return 1; } +/* + * Initialize mode type + */ Bool RRModeInit(void) { assert(num_modes == 0); assert(modes == NULL); - RRModeType = CreateNewResourceType(RRModeDestroyResource); + RRModeType = CreateNewResourceType(RRModeDestroyResource +#ifndef NXAGENT_SERVER + , "MODE" +#endif + ); if (!RRModeType) return FALSE; - RegisterResourceName(RRModeType, "MODE"); + return TRUE; } +/* + * Initialize mode type error value + */ +void +RRModeInitErrorValue(void) +{ +#ifndef NXAGENT_SERVER + SetResourceTypeErrorValue(RRModeType, RRErrorBase + BadRRMode); +#endif +} + int ProcRRCreateMode(ClientPtr client) { @@ -331,10 +344,11 @@ ProcRRCreateMode(ClientPtr client) char *name; int error, rc; RRModePtr mode; + int n; REQUEST_AT_LEAST_SIZE(xRRCreateModeReq); #ifndef NXAGENT_SERVER - rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); #else pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess); rc = pWin ? Success : BadWindow; @@ -346,24 +360,23 @@ ProcRRCreateMode(ClientPtr client) modeInfo = &stuff->modeInfo; name = (char *) (stuff + 1); - units_after = (stuff->length - (sizeof(xRRCreateModeReq) >> 2)); + units_after = (stuff->length - bytes_to_int32(sizeof(xRRCreateModeReq))); /* check to make sure requested name fits within the data provided */ - if ((int) (modeInfo->nameLength + 3) >> 2 > units_after) + if (bytes_to_int32(modeInfo->nameLength) > units_after) return BadLength; mode = RRModeCreateUser(pScreen, modeInfo, name, &error); if (!mode) return error; - rep.type = X_Reply; - rep.pad0 = 0; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.mode = mode->mode.id; + rep = (xRRCreateModeReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0, + .mode = mode->mode.id + }; if (client->swapped) { - int n; - swaps(&rep.sequenceNumber, n); swapl(&rep.length, n); swapl(&rep.mode, n); @@ -371,7 +384,7 @@ ProcRRCreateMode(ClientPtr client) WriteToClient(client, sizeof(xRRCreateModeReply), (char *) &rep); /* Drop out reference to this mode */ RRModeDestroy(mode); - return client->noClientException; + return Success; } int @@ -381,11 +394,8 @@ ProcRRDestroyMode(ClientPtr client) RRModePtr mode; REQUEST_SIZE_MATCH(xRRDestroyModeReq); - mode = LookupIDByType(stuff->mode, RRModeType); - if (!mode) { - client->errorValue = stuff->mode; - return RRErrorBase + BadRRMode; - } + VERIFY_RR_MODE(stuff->mode, mode, DixDestroyAccess); + if (!mode->userScreen) return BadMatch; if (mode->refcnt > 1) @@ -402,18 +412,8 @@ ProcRRAddOutputMode(ClientPtr client) RROutputPtr output; REQUEST_SIZE_MATCH(xRRAddOutputModeReq); - output = LookupOutput(client, stuff->output, DixReadAccess); - - if (!output) { - client->errorValue = stuff->output; - return RRErrorBase + BadRROutput; - } - - mode = LookupIDByType(stuff->mode, RRModeType); - if (!mode) { - client->errorValue = stuff->mode; - return RRErrorBase + BadRRMode; - } + VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess); + VERIFY_RR_MODE(stuff->mode, mode, DixUseAccess); return RROutputAddUserMode(output, mode); } @@ -426,18 +426,8 @@ ProcRRDeleteOutputMode(ClientPtr client) RROutputPtr output; REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq); - output = LookupOutput(client, stuff->output, DixReadAccess); - - if (!output) { - client->errorValue = stuff->output; - return RRErrorBase + BadRROutput; - } - - mode = LookupIDByType(stuff->mode, RRModeType); - if (!mode) { - client->errorValue = stuff->mode; - return RRErrorBase + BadRRMode; - } + VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess); + VERIFY_RR_MODE(stuff->mode, mode, DixUseAccess); return RROutputDeleteUserMode(output, mode); } diff --git a/nx-X11/programs/Xserver/randr/rrmonitor.c b/nx-X11/programs/Xserver/randr/rrmonitor.c new file mode 100644 index 000000000..fc9b9295b --- /dev/null +++ b/nx-X11/programs/Xserver/randr/rrmonitor.c @@ -0,0 +1,792 @@ +/* + * Copyright © 2014 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "randrstr.h" +#include "swaprep.h" +#ifndef NXAGENT_SERVER +#include "list.h" +#endif + +static Atom +RRMonitorCrtcName(RRCrtcPtr crtc) +{ + char name[20]; + + if (crtc->numOutputs) { + RROutputPtr output = crtc->outputs[0]; + return MakeAtom(output->name, output->nameLength, TRUE); + } + sprintf(name, "Monitor-%08lx", (unsigned long int) crtc->id); + return MakeAtom(name, strlen(name), TRUE); +} + +static Bool +RRMonitorCrtcPrimary(RRCrtcPtr crtc) +{ + ScreenPtr screen = crtc->pScreen; + rrScrPrivPtr pScrPriv = rrGetScrPriv(screen); + int o; + + for (o = 0; o < crtc->numOutputs; o++) + if (crtc->outputs[o] == pScrPriv->primaryOutput) + return TRUE; + return FALSE; +} + +#define DEFAULT_PIXELS_PER_MM (96.0 / 25.4) + +static void +RRMonitorGetCrtcGeometry(RRCrtcPtr crtc, RRMonitorGeometryPtr geometry) +{ + ScreenPtr screen = crtc->pScreen; + rrScrPrivPtr pScrPriv = rrGetScrPriv(screen); + BoxRec panned_area; + + /* Check to see if crtc is panned and return the full area when applicable. */ + if (pScrPriv && pScrPriv->rrGetPanning && + pScrPriv->rrGetPanning(screen, crtc, &panned_area, NULL, NULL) && + (panned_area.x2 > panned_area.x1) && + (panned_area.y2 > panned_area.y1)) { + geometry->box = panned_area; + } + else { + int width, height; + + RRCrtcGetScanoutSize(crtc, &width, &height); + geometry->box.x1 = crtc->x; + geometry->box.y1 = crtc->y; + geometry->box.x2 = geometry->box.x1 + width; + geometry->box.y2 = geometry->box.y1 + height; + } + if (crtc->numOutputs && crtc->outputs[0]->mmWidth && crtc->outputs[0]->mmHeight) { + RROutputPtr output = crtc->outputs[0]; + geometry->mmWidth = output->mmWidth; + geometry->mmHeight = output->mmHeight; + } else { + geometry->mmWidth = floor((geometry->box.x2 - geometry->box.x1) / DEFAULT_PIXELS_PER_MM + 0.5); + geometry->mmHeight = floor((geometry->box.y2 - geometry->box.y1) / DEFAULT_PIXELS_PER_MM + 0.5); + } +} + +static Bool +RRMonitorSetFromServer(RRCrtcPtr crtc, RRMonitorPtr monitor) +{ + int o; + + monitor->name = RRMonitorCrtcName(crtc); + monitor->pScreen = crtc->pScreen; + monitor->numOutputs = crtc->numOutputs; + monitor->outputs = xcalloc(crtc->numOutputs, sizeof(RRCrtc)); + if (!monitor->outputs) + return FALSE; + for (o = 0; o < crtc->numOutputs; o++) + monitor->outputs[o] = crtc->outputs[o]->id; + monitor->primary = RRMonitorCrtcPrimary(crtc); + monitor->automatic = TRUE; + RRMonitorGetCrtcGeometry(crtc, &monitor->geometry); + return TRUE; +} + +static Bool +RRMonitorAutomaticGeometry(RRMonitorPtr monitor) +{ + return (monitor->geometry.box.x1 == 0 && + monitor->geometry.box.y1 == 0 && + monitor->geometry.box.x2 == 0 && + monitor->geometry.box.y2 == 0); +} + +static void +RRMonitorGetGeometry(RRMonitorPtr monitor, RRMonitorGeometryPtr geometry) +{ + if (RRMonitorAutomaticGeometry(monitor) && monitor->numOutputs > 0) { + ScreenPtr screen = monitor->pScreen; + rrScrPrivPtr pScrPriv = rrGetScrPriv(screen); + RRMonitorGeometryRec first = { .box = {0, 0, 0, 0}, .mmWidth = 0, .mmHeight = 0 }; + RRMonitorGeometryRec this; + int c, o, co; + int active_crtcs = 0; + + *geometry = first; + for (o = 0; o < monitor->numOutputs; o++) { + RRCrtcPtr crtc = NULL; + Bool in_use = FALSE; + + for (c = 0; !in_use && c < pScrPriv->numCrtcs; c++) { + crtc = pScrPriv->crtcs[c]; + if (!crtc->mode) + continue; + for (co = 0; !in_use && co < crtc->numOutputs; co++) + if (monitor->outputs[o] == crtc->outputs[co]->id) + in_use = TRUE; + } + + if (!in_use) + continue; + + RRMonitorGetCrtcGeometry(crtc, &this); + + if (active_crtcs == 0) { + first = this; + *geometry = this; + } else { + geometry->box.x1 = min(this.box.x1, geometry->box.x1); + geometry->box.x2 = max(this.box.x2, geometry->box.x2); + geometry->box.y1 = min(this.box.y1, geometry->box.y1); + geometry->box.y2 = max(this.box.y2, geometry->box.y2); + } + active_crtcs++; + } + + /* Adjust physical sizes to account for total area */ + if (active_crtcs > 1 && first.box.x2 != first.box.x1 && first.box.y2 != first.box.y1) { + geometry->mmWidth = (this.box.x2 - this.box.x1) / (first.box.x2 - first.box.x1) * first.mmWidth; + geometry->mmHeight = (this.box.y2 - this.box.y1) / (first.box.y2 - first.box.y1) * first.mmHeight; + } + } else { + *geometry = monitor->geometry; + } +} + +static Bool +RRMonitorSetFromClient(RRMonitorPtr client_monitor, RRMonitorPtr monitor) +{ + monitor->name = client_monitor->name; + monitor->pScreen = client_monitor->pScreen; + monitor->numOutputs = client_monitor->numOutputs; + monitor->outputs = xcalloc(client_monitor->numOutputs, sizeof(RROutput)); + if (!monitor->outputs && client_monitor->numOutputs) + return FALSE; + memcpy(monitor->outputs, client_monitor->outputs, client_monitor->numOutputs * sizeof(RROutput)); + monitor->primary = client_monitor->primary; + monitor->automatic = client_monitor->automatic; + RRMonitorGetGeometry(client_monitor, &monitor->geometry); + return TRUE; +} + +typedef struct _rrMonitorList { + int num_client; + int num_server; + RRCrtcPtr *server_crtc; + int num_crtcs; + int client_primary; + int server_primary; +} RRMonitorListRec, *RRMonitorListPtr; + +static Bool +RRMonitorInitList(ScreenPtr screen, RRMonitorListPtr mon_list, Bool get_active) +{ + rrScrPrivPtr pScrPriv = rrGetScrPriv(screen); + int m, o, c, sc; + int numCrtcs; +#ifndef NXAGENT_SERVER + ScreenPtr slave; +#endif + + if (!RRGetInfo(screen, FALSE)) + return FALSE; + + /* Count the number of crtcs in this and any slave screens */ + numCrtcs = pScrPriv->numCrtcs; +#ifndef NXAGENT_SERVER + xorg_list_for_each_entry(slave, &screen->output_slave_list, output_head) { + rrScrPrivPtr pSlavePriv; + pSlavePriv = rrGetScrPriv(slave); + numCrtcs += pSlavePriv->numCrtcs; + } +#endif + mon_list->num_crtcs = numCrtcs; + + mon_list->server_crtc = xcalloc(numCrtcs * 2, sizeof(RRCrtcPtr)); + if (!mon_list->server_crtc) + return FALSE; + + /* Collect pointers to all of the active crtcs */ + c = 0; + for (sc = 0; sc < pScrPriv->numCrtcs; sc++, c++) { + if (pScrPriv->crtcs[sc]->mode != NULL) + mon_list->server_crtc[c] = pScrPriv->crtcs[sc]; + } + +#ifndef NXAGENT_SERVER + xorg_list_for_each_entry(slave, &screen->output_slave_list, output_head) { + rrScrPrivPtr pSlavePriv; + pSlavePriv = rrGetScrPriv(slave); + for (sc = 0; sc < pSlavePriv->numCrtcs; sc++, c++) { + if (pSlavePriv->crtcs[sc]->mode != NULL) + mon_list->server_crtc[c] = pSlavePriv->crtcs[sc]; + } + } +#endif + + /* Walk the list of client-defined monitors, clearing the covered + * CRTCs from the full list and finding whether one of the + * monitors is primary + */ + mon_list->num_client = pScrPriv->numMonitors; + mon_list->client_primary = -1; + + for (m = 0; m < pScrPriv->numMonitors; m++) { + RRMonitorPtr monitor = pScrPriv->monitors[m]; + if (get_active) { + RRMonitorGeometryRec geom; + + RRMonitorGetGeometry(monitor, &geom); + if (geom.box.x2 - geom.box.x1 == 0 || + geom.box.y2 - geom.box.y1 == 0) { + mon_list->num_client--; + continue; + } + } + if (monitor->primary && mon_list->client_primary == -1) + mon_list->client_primary = m; + for (o = 0; o < monitor->numOutputs; o++) { + for (c = 0; c < numCrtcs; c++) { + RRCrtcPtr crtc = mon_list->server_crtc[c]; + if (crtc) { + int co; + for (co = 0; co < crtc->numOutputs; co++) + if (crtc->outputs[co]->id == monitor->outputs[o]) { + mon_list->server_crtc[c] = NULL; + break; + } + } + } + } + } + + /* Now look at the active CRTCs, and count + * those not covered by a client monitor, as well + * as finding whether one of them is marked primary + */ + mon_list->num_server = 0; + mon_list->server_primary = -1; + + for (c = 0; c < mon_list->num_crtcs; c++) { + RRCrtcPtr crtc = mon_list->server_crtc[c]; + + if (!crtc) + continue; + + mon_list->num_server++; + + if (RRMonitorCrtcPrimary(crtc) && mon_list->server_primary == -1) + mon_list->server_primary = c; + } + return TRUE; +} + +static void +RRMonitorFiniList(RRMonitorListPtr list) +{ + xfree(list->server_crtc); +} + +/* Construct a complete list of protocol-visible monitors, including + * the manually generated ones as well as those generated + * automatically from the remaining CRCTs + */ + +Bool +RRMonitorMakeList(ScreenPtr screen, Bool get_active, RRMonitorPtr * monitors_ret, int *nmon_ret) +{ + rrScrPrivPtr pScrPriv = rrGetScrPriv(screen); + RRMonitorListRec list; + int m, c; + RRMonitorPtr mon, monitors; + Bool has_primary = FALSE; + + if (!pScrPriv) + return FALSE; + + if (!RRMonitorInitList(screen, &list, get_active)) + return FALSE; + + monitors = xcalloc(list.num_client + list.num_server, sizeof(RRMonitorRec)); + if (!monitors) { + RRMonitorFiniList(&list); + return FALSE; + } + + mon = monitors; + + /* Fill in the primary monitor data first + */ + if (list.client_primary >= 0) { + RRMonitorSetFromClient(pScrPriv->monitors[list.client_primary], mon); + mon++; + } else if (list.server_primary >= 0) { + RRMonitorSetFromServer(list.server_crtc[list.server_primary], mon); + mon++; + } + + /* Fill in the client-defined monitors next + */ + for (m = 0; m < pScrPriv->numMonitors; m++) { + if (m == list.client_primary) + continue; + if (get_active) { + RRMonitorGeometryRec geom; + + RRMonitorGetGeometry(pScrPriv->monitors[m], &geom); + if (geom.box.x2 - geom.box.x1 == 0 || + geom.box.y2 - geom.box.y1 == 0) { + continue; + } + } + RRMonitorSetFromClient(pScrPriv->monitors[m], mon); + if (has_primary) + mon->primary = FALSE; + else if (mon->primary) + has_primary = TRUE; + mon++; + } + + /* And finish with the list of crtc-inspired monitors + */ + for (c = 0; c < list.num_crtcs; c++) { + RRCrtcPtr crtc = list.server_crtc[c]; + if (c == list.server_primary && list.client_primary < 0) + continue; + + if (!list.server_crtc[c]) + continue; + + RRMonitorSetFromServer(crtc, mon); + if (has_primary) + mon->primary = FALSE; + else if (mon->primary) + has_primary = TRUE; + mon++; + } + + RRMonitorFiniList(&list); + *nmon_ret = list.num_client + list.num_server; + *monitors_ret = monitors; + return TRUE; +} + +int +RRMonitorCountList(ScreenPtr screen) +{ + RRMonitorListRec list; + int nmon; + + if (!RRMonitorInitList(screen, &list, FALSE)) + return -1; + nmon = list.num_client + list.num_server; + RRMonitorFiniList(&list); + return nmon; +} + +void +RRMonitorFree(RRMonitorPtr monitor) +{ + xfree(monitor); +} + +RRMonitorPtr +RRMonitorAlloc(int noutput) +{ + RRMonitorPtr monitor; + + monitor = xcalloc(1, sizeof(RRMonitorRec) + noutput * sizeof(RROutput)); + if (!monitor) + return NULL; + monitor->numOutputs = noutput; + monitor->outputs = (RROutput *) (monitor + 1); + return monitor; +} + +static int +RRMonitorDelete(ClientPtr client, ScreenPtr screen, Atom name) +{ + rrScrPrivPtr pScrPriv = rrGetScrPriv(screen); + int m; + + if (!pScrPriv) { + client->errorValue = name; + return BadAtom; + } + + for (m = 0; m < pScrPriv->numMonitors; m++) { + RRMonitorPtr monitor = pScrPriv->monitors[m]; + if (monitor->name == name) { + memmove(pScrPriv->monitors + m, pScrPriv->monitors + m + 1, + (pScrPriv->numMonitors - (m + 1)) * sizeof(RRMonitorPtr)); + --pScrPriv->numMonitors; + RRMonitorFree(monitor); + return Success; + } + } + + client->errorValue = name; + return BadValue; +} + +static Bool +RRMonitorMatchesOutputName(ScreenPtr screen, Atom name) +{ + rrScrPrivPtr pScrPriv = rrGetScrPriv(screen); + int o; + const char *str = NameForAtom(name); + int len = strlen(str); + + for (o = 0; o < pScrPriv->numOutputs; o++) { + RROutputPtr output = pScrPriv->outputs[o]; + + if (output->nameLength == len && !memcmp(output->name, str, len)) + return TRUE; + } + return FALSE; +} + +int +RRMonitorAdd(ClientPtr client, ScreenPtr screen, RRMonitorPtr monitor) +{ + rrScrPrivPtr pScrPriv = rrGetScrPriv(screen); + int m; +#ifndef NXAGENT_SERVER + ScreenPtr slave; +#endif + RRMonitorPtr *monitors; + + if (!pScrPriv) + return BadAlloc; + + /* 'name' must not match the name of any Output on the screen, or + * a Value error results. + */ + + if (RRMonitorMatchesOutputName(screen, monitor->name)) { + client->errorValue = monitor->name; + return BadValue; + } + +#ifndef NXAGENT_SERVER + xorg_list_for_each_entry(slave, &screen->output_slave_list, output_head) { + if (RRMonitorMatchesOutputName(slave, monitor->name)) { + client->errorValue = monitor->name; + return BadValue; + } + } +#endif + + /* 'name' must not match the name of any Monitor on the screen, or + * a Value error results. + */ + + for (m = 0; m < pScrPriv->numMonitors; m++) { + if (pScrPriv->monitors[m]->name == monitor->name) { + client->errorValue = monitor->name; + return BadValue; + } + } + + /* Allocate space for the new pointer. This is done before + * removing matching monitors as it may fail, and the request + * needs to not have any side-effects on failure + */ + if (pScrPriv->numMonitors) +#ifndef NXAGENT_SERVER + monitors = reallocarray(pScrPriv->monitors, + pScrPriv->numMonitors + 1, + sizeof(RRMonitorPtr)); +#else /* !defined(NXAGENT_SERVER) */ + monitors = xrealloc(pScrPriv->monitors, + (pScrPriv->numMonitors + 1) * sizeof(RRMonitorPtr)); +#endif /* !defined(NXAGENT_SERVER) */ + else + monitors = xalloc(sizeof(RRMonitorPtr)); + + if (!monitors) + return BadAlloc; + + pScrPriv->monitors = monitors; + + for (m = 0; m < pScrPriv->numMonitors; m++) { + RRMonitorPtr existing = pScrPriv->monitors[m]; + int o, eo; + + /* If 'name' matches an existing Monitor on the screen, the + * existing one will be deleted as if RRDeleteMonitor were called. + */ + if (existing->name == monitor->name) { + (void) RRMonitorDelete(client, screen, existing->name); + continue; + } + + /* For each output in 'info.outputs', each one is removed from all + * pre-existing Monitors. If removing the output causes the list + * of outputs for that Monitor to become empty, then that + * Monitor will be deleted as if RRDeleteMonitor were called. + */ + + for (eo = 0; eo < existing->numOutputs; eo++) { + for (o = 0; o < monitor->numOutputs; o++) { + if (monitor->outputs[o] == existing->outputs[eo]) { + memmove(existing->outputs + eo, existing->outputs + eo + 1, + (existing->numOutputs - (eo + 1)) * sizeof(RROutput)); + --existing->numOutputs; + --eo; + break; + } + } + if (existing->numOutputs == 0) { + (void) RRMonitorDelete(client, screen, existing->name); + break; + } + } + if (monitor->primary) + existing->primary = FALSE; + } + + /* Add the new one to the list + */ + pScrPriv->monitors[pScrPriv->numMonitors++] = monitor; + + return Success; +} + +void +RRMonitorFreeList(RRMonitorPtr monitors, int nmon) +{ + int m; + + for (m = 0; m < nmon; m++) + xfree(monitors[m].outputs); + xfree(monitors); +} + +void +RRMonitorInit(ScreenPtr screen) +{ + rrScrPrivPtr pScrPriv = rrGetScrPriv(screen); + + if (!pScrPriv) + return; + + pScrPriv->numMonitors = 0; + pScrPriv->monitors = NULL; +} + +void +RRMonitorClose(ScreenPtr screen) +{ + rrScrPrivPtr pScrPriv = rrGetScrPriv(screen); + int m; + + if (!pScrPriv) + return; + + for (m = 0; m < pScrPriv->numMonitors; m++) + RRMonitorFree(pScrPriv->monitors[m]); + xfree(pScrPriv->monitors); + pScrPriv->monitors = NULL; + pScrPriv->numMonitors = 0; +} + +static CARD32 +RRMonitorTimestamp(ScreenPtr screen) +{ + rrScrPrivPtr pScrPriv = rrGetScrPriv(screen); + + /* XXX should take client monitor changes into account */ + return pScrPriv->lastConfigTime.milliseconds; +} + +int +ProcRRGetMonitors(ClientPtr client) +{ + REQUEST(xRRGetMonitorsReq); + xRRGetMonitorsReply rep = { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0, + }; + WindowPtr window; + ScreenPtr screen; + int r; + RRMonitorPtr monitors; + int nmonitors; + int noutputs; + int m, n; + Bool get_active; + + REQUEST_SIZE_MATCH(xRRGetMonitorsReq); +#ifndef NXAGENT_SERVER + r = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess); +#else + window = SecurityLookupWindow(stuff->window, client, SecurityReadAccess); + r = window ? Success : BadWindow; +#endif + + if (r != Success) + return r; + screen = window->drawable.pScreen; + + get_active = stuff->get_active; + if (!RRMonitorMakeList(screen, get_active, &monitors, &nmonitors)) + return BadAlloc; + + rep.timestamp = RRMonitorTimestamp(screen); + + noutputs = 0; + for (m = 0; m < nmonitors; m++) { + rep.length += SIZEOF(xRRMonitorInfo) >> 2; + rep.length += monitors[m].numOutputs; + noutputs += monitors[m].numOutputs; + } + + rep.nmonitors = nmonitors; + rep.noutputs = noutputs; + + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.timestamp, n); + swapl(&rep.nmonitors, n); + swapl(&rep.noutputs, n); + } + WriteToClient(client, sizeof(xRRGetMonitorsReply), (char *) &rep); + + client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write; + + for (m = 0; m < nmonitors; m++) { + RRMonitorPtr monitor = &monitors[m]; + xRRMonitorInfo info = { + .name = monitor->name, + .primary = monitor->primary, + .automatic = monitor->automatic, + .noutput = monitor->numOutputs, + .x = monitor->geometry.box.x1, + .y = monitor->geometry.box.y1, + .width = monitor->geometry.box.x2 - monitor->geometry.box.x1, + .height = monitor->geometry.box.y2 - monitor->geometry.box.y1, + .widthInMillimeters = monitor->geometry.mmWidth, + .heightInMillimeters = monitor->geometry.mmHeight, + }; + if (client->swapped) { + swapl(&info.name, n); + swaps(&info.noutput, n); + swaps(&info.x, n); + swaps(&info.y, n); + swaps(&info.width, n); + swaps(&info.height, n); + swapl(&info.widthInMillimeters, n); + swapl(&info.heightInMillimeters, n); + } + + WriteToClient(client, sizeof(xRRMonitorInfo), (char *) &info); + WriteSwappedDataToClient(client, monitor->numOutputs * sizeof(RROutput), + monitor->outputs); + } + + RRMonitorFreeList(monitors, nmonitors); + + return Success; +} + +int +ProcRRSetMonitor(ClientPtr client) +{ + REQUEST(xRRSetMonitorReq); + WindowPtr window; + ScreenPtr screen; + RRMonitorPtr monitor; + int r; + + REQUEST_AT_LEAST_SIZE(xRRSetMonitorReq); + + if (stuff->monitor.noutput != stuff->length - (SIZEOF(xRRSetMonitorReq) >> 2)) + return BadLength; + +#ifndef NXAGENT_SERVER + r = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess); +#else + window = SecurityLookupWindow(stuff->window, client, SecurityReadAccess); + r = window ? Success : BadWindow; +#endif + + if (r != Success) + return r; + screen = window->drawable.pScreen; + + if (!ValidAtom(stuff->monitor.name)) + return BadAtom; + + /* Allocate the new monitor */ + monitor = RRMonitorAlloc(stuff->monitor.noutput); + if (!monitor) + return BadAlloc; + + /* Fill in the bits from the request */ + monitor->pScreen = screen; + monitor->name = stuff->monitor.name; + monitor->primary = stuff->monitor.primary; + monitor->automatic = FALSE; + memcpy(monitor->outputs, stuff + 1, stuff->monitor.noutput * sizeof(RROutput)); + monitor->geometry.box.x1 = stuff->monitor.x; + monitor->geometry.box.y1 = stuff->monitor.y; + monitor->geometry.box.x2 = stuff->monitor.x + stuff->monitor.width; + monitor->geometry.box.y2 = stuff->monitor.y + stuff->monitor.height; + monitor->geometry.mmWidth = stuff->monitor.widthInMillimeters; + monitor->geometry.mmHeight = stuff->monitor.heightInMillimeters; + + r = RRMonitorAdd(client, screen, monitor); + if (r == Success) + RRSendConfigNotify(screen); + else + RRMonitorFree(monitor); + return r; +} + +int +ProcRRDeleteMonitor(ClientPtr client) +{ + REQUEST(xRRDeleteMonitorReq); + WindowPtr window; + ScreenPtr screen; + int r; + + REQUEST_SIZE_MATCH(xRRDeleteMonitorReq); +#ifndef NXAGENT_SERVER + r = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess); +#else + window = SecurityLookupWindow(stuff->window, client, SecurityReadAccess); + r = window ? Success : BadWindow; +#endif + + if (r != Success) + return r; + screen = window->drawable.pScreen; + + if (!ValidAtom(stuff->name)) { + client->errorValue = stuff->name; + return BadAtom; + } + + r = RRMonitorDelete(client, screen, stuff->name); + if (r == Success) + RRSendConfigNotify(screen); + return r; +} diff --git a/nx-X11/programs/Xserver/randr/rroutput.c b/nx-X11/programs/Xserver/randr/rroutput.c index 523ee55d8..2628fabb0 100644 --- a/nx-X11/programs/Xserver/randr/rroutput.c +++ b/nx-X11/programs/Xserver/randr/rroutput.c @@ -1,5 +1,6 @@ /* * Copyright © 2006 Keith Packard + * Copyright © 2008 Red Hat, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -21,7 +22,6 @@ */ #include "randrstr.h" -#include "registry.h" RESTYPE RROutputType; @@ -31,15 +31,30 @@ RESTYPE RROutputType; void RROutputChanged(RROutputPtr output, Bool configChanged) { + /* set changed bits on the master screen only */ ScreenPtr pScreen = output->pScreen; + rrScrPrivPtr mastersp; output->changed = TRUE; - if (pScreen) { - rrScrPriv(pScreen); - pScrPriv->changed = TRUE; - if (configChanged) - pScrPriv->configChanged = TRUE; + if (!pScreen) + return; + +#ifndef NXAGENT_SERVER + if (pScreen->isGPU) { + ScreenPtr master = pScreen->current_master; + if (!master) + return; + mastersp = rrGetScrPriv(master); } + else +#endif + { + mastersp = rrGetScrPriv(pScreen); + } + + RRSetChanged(pScreen); + if (configChanged) + mastersp->configChanged = TRUE; } /* @@ -60,8 +75,13 @@ RROutputCreate(ScreenPtr pScreen, pScrPriv = rrGetScrPriv(pScreen); if (pScrPriv->numOutputs) +#ifndef NXAGENT_SERVER + outputs = reallocarray(pScrPriv->outputs, + pScrPriv->numOutputs + 1, sizeof(RROutputPtr)); +#else /* !defined(NXAGENT_SERVER) */ outputs = xrealloc(pScrPriv->outputs, (pScrPriv->numOutputs + 1) * sizeof(RROutputPtr)); +#endif /* !defined(NXAGENT_SERVER) */ else outputs = xalloc(sizeof(RROutputPtr)); if (!outputs) @@ -101,6 +121,9 @@ RROutputCreate(ScreenPtr pScreen, return NULL; pScrPriv->outputs[pScrPriv->numOutputs++] = output; + + RRResourcesChanged(pScreen); + return output; } @@ -121,14 +144,17 @@ RROutputSetClones(RROutputPtr output, RROutputPtr * clones, int numClones) return TRUE; } if (numClones) { +#ifndef NXAGENT_SERVER + newClones = xallocarray(numClones, sizeof(RROutputPtr)); +#else /* !defined(NXAGENT_SERVER) */ newClones = xalloc(numClones * sizeof(RROutputPtr)); +#endif /* !defined(NXAGENT_SERVER) */ if (!newClones) return FALSE; } else newClones = NULL; - if (output->clones) - xfree(output->clones); + xfree(output->clones); memcpy(newClones, clones, numClones * sizeof(RROutputPtr)); output->clones = newClones; output->numClones = numClones; @@ -155,7 +181,11 @@ RROutputSetModes(RROutputPtr output, } if (numModes) { +#ifndef NXAGENT_SERVER + newModes = xallocarray(numModes, sizeof(RRModePtr)); +#else /* !defined(NXAGENT_SERVER) */ newModes = xalloc(numModes * sizeof(RRModePtr)); +#endif /* !defined(NXAGENT_SERVER) */ if (!newModes) return FALSE; } @@ -198,8 +228,13 @@ RROutputAddUserMode(RROutputPtr output, RRModePtr mode) return BadMatch; if (output->userModes) +#ifndef NXAGENT_SERVER + newModes = reallocarray(output->userModes, + output->numUserModes + 1, sizeof(RRModePtr)); +#else /* !defined(NXAGENT_SERVER) */ newModes = xrealloc(output->userModes, (output->numUserModes + 1) * sizeof(RRModePtr)); +#endif /* !defined(NXAGENT_SERVER) */ else newModes = xalloc(sizeof(RRModePtr)); if (!newModes) @@ -254,14 +289,17 @@ RROutputSetCrtcs(RROutputPtr output, RRCrtcPtr * crtcs, int numCrtcs) return TRUE; } if (numCrtcs) { +#ifndef NXAGENT_SERVER + newCrtcs = xallocarray(numCrtcs, sizeof(RRCrtcPtr)); +#else /* !defined(NXAGENT_SERVER) */ newCrtcs = xalloc(numCrtcs * sizeof(RRCrtcPtr)); +#endif /* !defined(NXAGENT_SERVER) */ if (!newCrtcs) return FALSE; } else newCrtcs = NULL; - if (output->crtcs) - xfree(output->crtcs); + xfree(output->crtcs); memcpy(newCrtcs, crtcs, numCrtcs * sizeof(RRCrtcPtr)); output->crtcs = newCrtcs; output->numCrtcs = numCrtcs; @@ -307,29 +345,25 @@ RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output) ScreenPtr pScreen = pWin->drawable.pScreen; rrScrPriv(pScreen); - xRROutputChangeNotifyEvent oe; RRCrtcPtr crtc = output->crtc; - RRModePtr mode = crtc ? crtc->mode : 0; - - oe.type = RRNotify + RREventBase; - oe.subCode = RRNotify_OutputChange; - oe.sequenceNumber = client->sequence; - oe.timestamp = pScrPriv->lastSetTime.milliseconds; - oe.configTimestamp = pScrPriv->lastConfigTime.milliseconds; - oe.window = pWin->drawable.id; - oe.output = output->id; - if (crtc) { - oe.crtc = crtc->id; - oe.mode = mode ? mode->mode.id : None; - oe.rotation = crtc->rotation; - } - else { - oe.crtc = None; - oe.mode = None; - oe.rotation = RR_Rotate_0; - } - oe.connection = output->connection; - oe.subpixelOrder = output->subpixelOrder; + RRModePtr mode = crtc ? crtc->mode : NULL; + + xRROutputChangeNotifyEvent oe = { + .type = RRNotify + RREventBase, + .subCode = RRNotify_OutputChange, +#ifdef NXAGENT_SERVER + .sequenceNumber = client->sequence, +#endif + .timestamp = pScrPriv->lastSetTime.milliseconds, + .configTimestamp = pScrPriv->lastConfigTime.milliseconds, + .window = pWin->drawable.id, + .output = output->id, + .crtc = crtc ? crtc->id : None, + .mode = mode ? mode->mode.id : None, + .rotation = crtc ? crtc->rotation : RR_Rotate_0, + .connection = output->connection, + .subpixelOrder = output->subpixelOrder + }; WriteEventsToClient(client, 1, (xEvent *) &oe); } @@ -353,6 +387,9 @@ RROutputDestroyResource(void *value, XID pid) rrScrPriv(pScreen); int i; + if (pScrPriv->primaryOutput == output) + pScrPriv->primaryOutput = NULL; + for (i = 0; i < pScrPriv->numOutputs; i++) { if (pScrPriv->outputs[i] == output) { memmove(pScrPriv->outputs + i, pScrPriv->outputs + i + 1, @@ -361,6 +398,8 @@ RROutputDestroyResource(void *value, XID pid) break; } } + + RRResourcesChanged(pScreen); } if (output->modes) { for (m = 0; m < output->numModes; m++) @@ -370,13 +409,10 @@ RROutputDestroyResource(void *value, XID pid) for (m = 0; m < output->numUserModes; m++) RRModeDestroy(output->userModes[m]); - if (output->userModes) - xfree(output->userModes); + xfree(output->userModes); - if (output->crtcs) - xfree(output->crtcs); - if (output->clones) - xfree(output->clones); + xfree(output->crtcs); + xfree(output->clones); RRDeleteAllOutputProperties(output); xfree(output); return 1; @@ -388,13 +424,28 @@ RROutputDestroyResource(void *value, XID pid) Bool RROutputInit(void) { - RROutputType = CreateNewResourceType(RROutputDestroyResource); + RROutputType = CreateNewResourceType(RROutputDestroyResource +#ifndef NXAGENT_SERVER + , "OUTPUT" +#endif + ); if (!RROutputType) return FALSE; - RegisterResourceName(RROutputType, "OUTPUT"); + return TRUE; } +/* + * Initialize output type error value + */ +void +RROutputInitErrorValue(void) +{ +#ifndef NXAGENT_SERVER + SetResourceTypeErrorValue(RROutputType, RRErrorBase + BadRROutput); +#endif +} + #define OutputInfoExtra (SIZEOF(xRRGetOutputInfoReply) - 32) int @@ -411,41 +462,38 @@ ProcRRGetOutputInfo(ClientPtr client) RRMode *modes; RROutput *clones; char *name; - int i, n; + int i; + int n; REQUEST_SIZE_MATCH(xRRGetOutputInfoReq); - output = LookupOutput(client, stuff->output, DixReadAccess); - - if (!output) { - client->errorValue = stuff->output; - return RRErrorBase + BadRROutput; - } + VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess); pScreen = output->pScreen; pScrPriv = rrGetScrPriv(pScreen); - rep.type = X_Reply; - rep.status = RRSetConfigSuccess; - rep.sequenceNumber = client->sequence; - rep.length = OutputInfoExtra >> 2; - rep.timestamp = pScrPriv->lastSetTime.milliseconds; - rep.crtc = output->crtc ? output->crtc->id : None; - rep.mmWidth = output->mmWidth; - rep.mmHeight = output->mmHeight; - rep.connection = output->connection; - rep.subpixelOrder = output->subpixelOrder; - rep.nCrtcs = output->numCrtcs; - rep.nModes = output->numModes + output->numUserModes; - rep.nPreferred = output->numPreferred; - rep.nClones = output->numClones; - rep.nameLength = output->nameLength; - + rep = (xRRGetOutputInfoReply) { + .type = X_Reply, + .status = RRSetConfigSuccess, + .sequenceNumber = client->sequence, + .length = bytes_to_int32(OutputInfoExtra), + .timestamp = pScrPriv->lastSetTime.milliseconds, + .crtc = output->crtc ? output->crtc->id : None, + .mmWidth = output->mmWidth, + .mmHeight = output->mmHeight, + .connection = output->connection, + .subpixelOrder = output->subpixelOrder, + .nCrtcs = output->numCrtcs, + .nModes = output->numModes + output->numUserModes, + .nPreferred = output->numPreferred, + .nClones = output->numClones, + .nameLength = output->nameLength + }; extraLen = ((output->numCrtcs + - output->numModes + output->numUserModes + - output->numClones + ((rep.nameLength + 3) >> 2)) << 2); + output->numModes + output->numUserModes + + output->numClones + bytes_to_int32(rep.nameLength)) << 2); if (extraLen) { - rep.length += extraLen >> 2; + rep.length += bytes_to_int32(extraLen); extra = xalloc(extraLen); if (!extra) return BadAlloc; @@ -486,6 +534,7 @@ ProcRRGetOutputInfo(ClientPtr client) swapl(&rep.mmHeight, n); swaps(&rep.nCrtcs, n); swaps(&rep.nModes, n); + swaps(&rep.nPreferred, n); swaps(&rep.nClones, n); swaps(&rep.nameLength, n); } @@ -495,5 +544,130 @@ ProcRRGetOutputInfo(ClientPtr client) xfree(extra); } - return client->noClientException; + return Success; +} + +static void +RRSetPrimaryOutput(ScreenPtr pScreen, rrScrPrivPtr pScrPriv, RROutputPtr output) +{ + if (pScrPriv->primaryOutput == output) + return; + + /* clear the old primary */ + if (pScrPriv->primaryOutput) { + RROutputChanged(pScrPriv->primaryOutput, 0); + pScrPriv->primaryOutput = NULL; + } + + /* set the new primary */ + if (output) { + pScrPriv->primaryOutput = output; + RROutputChanged(output, 0); + } + + pScrPriv->layoutChanged = TRUE; + + RRTellChanged(pScreen); +} + +int +ProcRRSetOutputPrimary(ClientPtr client) +{ + REQUEST(xRRSetOutputPrimaryReq); + RROutputPtr output = NULL; + WindowPtr pWin; + rrScrPrivPtr pScrPriv; + int ret; +#ifndef NXAGENT_SERVER + ScreenPtr slave; +#endif + + REQUEST_SIZE_MATCH(xRRSetOutputPrimaryReq); + +#ifndef NXAGENT_SERVER + ret = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); +#else + pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess); + ret = pWin ? Success : BadWindow; +#endif + + if (ret != Success) + return ret; + + if (stuff->output) { + VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess); + +#ifndef NXAGENT_SERVER + if (!output->pScreen->isGPU && output->pScreen != pWin->drawable.pScreen) { + client->errorValue = stuff->window; + return BadMatch; + } + if (output->pScreen->isGPU && + output->pScreen->current_master != pWin->drawable.pScreen) { + client->errorValue = stuff->window; + return BadMatch; + } +#endif + } + + pScrPriv = rrGetScrPriv(pWin->drawable.pScreen); + if (pScrPriv) + { + RRSetPrimaryOutput(pWin->drawable.pScreen, pScrPriv, output); + +#ifndef NXAGENT_SERVER + xorg_list_for_each_entry(slave, + &pWin->drawable.pScreen->output_slave_list, + output_head) { + rrScrPrivPtr pSlavePriv; + pSlavePriv = rrGetScrPriv(slave); + + RRSetPrimaryOutput(slave, pSlavePriv, output); + } +#endif + } + + return Success; +} + +int +ProcRRGetOutputPrimary(ClientPtr client) +{ + REQUEST(xRRGetOutputPrimaryReq); + WindowPtr pWin; + rrScrPrivPtr pScrPriv; + xRRGetOutputPrimaryReply rep; + RROutputPtr primary = NULL; + int rc; + int n; + + REQUEST_SIZE_MATCH(xRRGetOutputPrimaryReq); + +#ifndef NXAGENT_SERVER + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); +#else + pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess); + rc = pWin ? Success : BadWindow; +#endif + + if (rc != Success) + return rc; + + pScrPriv = rrGetScrPriv(pWin->drawable.pScreen); + if (pScrPriv) + primary = pScrPriv->primaryOutput; + + rep = (xRRGetOutputPrimaryReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .output = primary ? primary->id : None + }; + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.output, n); + } + + WriteToClient(client, sizeof(xRRGetOutputPrimaryReply), (char *) &rep); + + return Success; } diff --git a/nx-X11/programs/Xserver/randr/rrpointer.c b/nx-X11/programs/Xserver/randr/rrpointer.c index 811310985..ace7d36a2 100644 --- a/nx-X11/programs/Xserver/randr/rrpointer.c +++ b/nx-X11/programs/Xserver/randr/rrpointer.c @@ -21,6 +21,7 @@ */ #include "randrstr.h" +#include "inputstr.h" /* * When the pointer moves, check to see if the specified position is outside @@ -51,7 +52,11 @@ RRCrtcContainsPosition(RRCrtcPtr crtc, int x, int y) * Find the CRTC nearest the specified position, ignoring 'skip' */ static void -RRPointerToNearestCrtc(ScreenPtr pScreen, int x, int y, RRCrtcPtr skip) +RRPointerToNearestCrtc( +#ifndef NXAGENT_SERVER + DeviceIntPtr pDev, +#endif /* !defined(NXAGENT_SERVER) */ + ScreenPtr pScreen, int x, int y, RRCrtcPtr skip) { rrScrPriv(pScreen); int c; @@ -75,25 +80,31 @@ RRPointerToNearestCrtc(ScreenPtr pScreen, int x, int y, RRCrtcPtr skip) if (x < crtc->x) dx = crtc->x - x; - else if (x > crtc->x + scan_width) - dx = x - (crtc->x + scan_width); + else if (x > crtc->x + scan_width - 1) + dx = crtc->x + (scan_width - 1) - x; else dx = 0; if (y < crtc->y) - dy = crtc->y - x; - else if (y > crtc->y + scan_height) - dy = y - (crtc->y + scan_height); + dy = crtc->y - y; + else if (y > crtc->y + scan_height - 1) + dy = crtc->y + (scan_height - 1) - y; else dy = 0; - dist = dx + dy; + dist = dx * dx + dy * dy; if (!nearest || dist < best) { nearest = crtc; best_dx = dx; best_dy = dy; + best = dist; } } if (best_dx || best_dy) - (*pScreen->SetCursorPosition) (pScreen, x + best_dx, y + best_dy, TRUE); + (*pScreen->SetCursorPosition) ( +#ifndef NXAGENT_SERVER + pDev, +#endif /* !defined(NXAGENT_SERVER) */ + pScreen, x + best_dx, y + best_dy, + TRUE); pScrPriv->pointerCrtc = nearest; } @@ -120,22 +131,52 @@ RRPointerMoved(ScreenPtr pScreen, int x, int y) } /* None contain pointer, find nearest */ - RRPointerToNearestCrtc(pScreen, x, y, pointerCrtc); + ErrorF("RRPointerMoved: Untested, may cause \"bogus pointer event\"\n"); + RRPointerToNearestCrtc( +#ifndef NXAGENT_SERVER + inputInfo.pointer, +#endif /* !defined(NXAGENT_SERVER) */ + pScreen, x, y, pointerCrtc); } /* - * When the screen is reconfigured, move the pointer to the nearest + * When the screen is reconfigured, move all pointers to the nearest * CRTC */ void RRPointerScreenConfigured(ScreenPtr pScreen) { - WindowPtr pRoot = GetCurrentRootWindow(); - ScreenPtr pCurrentScreen = pRoot ? pRoot->drawable.pScreen : NULL; + WindowPtr pRoot; + ScreenPtr pCurrentScreen; int x, y; - if (pScreen != pCurrentScreen) - return; - GetSpritePosition(&x, &y); - RRPointerToNearestCrtc(pScreen, x, y, NULL); +#ifndef NXAGENT_SERVER + DeviceIntPtr pDev; + + for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { + if (IsPointerDevice(pDev)) { +#endif /* NXAGENT_SERVER */ + pRoot = GetCurrentRootWindow( +#ifndef NXAGENT_SERVER + pDev +#endif /* NXAGENT_SERVER */ + ); + pCurrentScreen = pRoot ? pRoot->drawable.pScreen : NULL; + + if (pScreen == pCurrentScreen) { + GetSpritePosition( +#ifndef NXAGENT_SERVER + pDev, +#endif /* NXAGENT_SERVER */ + &x, &y); + RRPointerToNearestCrtc( +#ifndef NXAGENT_SERVER + pDev, +#endif /* NXAGENT_SERVER */ + pScreen, x, y, NULL); +#ifndef NXAGENT_SERVER + } + } +#endif /* NXAGENT_SERVER */ + } } diff --git a/nx-X11/programs/Xserver/randr/rrproperty.c b/nx-X11/programs/Xserver/randr/rrproperty.c index 0bccb0c68..741d0310e 100644 --- a/nx-X11/programs/Xserver/randr/rrproperty.c +++ b/nx-X11/programs/Xserver/randr/rrproperty.c @@ -24,33 +24,76 @@ #include "propertyst.h" #include "swaprep.h" +static int +DeliverPropertyEvent(WindowPtr pWin, void *value) +{ + xRROutputPropertyNotifyEvent *event = value; + RREventPtr *pHead, pRREvent; + +#ifndef NXAGENT_SERVER + dixLookupResourceByType((void **) &pHead, pWin->drawable.id, + RREventType, serverClient, DixReadAccess); +#else /* !defined(NXAGENT_SERVER) */ + pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, RREventType); +#endif /* !defined(NXAGENT_SERVER) */ + if (!pHead) + return WT_WALKCHILDREN; + + for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) { + if (!(pRREvent->mask & RROutputPropertyNotifyMask)) + continue; + +#ifdef NXAGENT_SERVER + event->sequenceNumber = pRREvent->client->sequence; +#endif + event->window = pRREvent->window->drawable.id; + WriteEventsToClient(pRREvent->client, 1, (xEvent *) event); + } + + return WT_WALKCHILDREN; +} + static void -RRDeliverEvent(ScreenPtr pScreen, xEvent *event, CARD32 mask) +RRDeliverPropertyEvent(ScreenPtr pScreen, xEvent *event) { + if (!(dispatchException & (DE_RESET | DE_TERMINATE))) + WalkTree(pScreen, DeliverPropertyEvent, event); +} +static void +RRDestroyOutputProperty(RRPropertyPtr prop) +{ + xfree(prop->valid_values); + xfree(prop->current.data); + xfree(prop->pending.data); + xfree(prop); +} + +static void +RRDeleteProperty(RROutputRec * output, RRPropertyRec * prop) +{ + xRROutputPropertyNotifyEvent event = { + .type = RREventBase + RRNotify, + .subCode = RRNotify_OutputProperty, + .output = output->id, + .state = PropertyDelete, + .atom = prop->propertyName, + .timestamp = currentTime.milliseconds + }; + + RRDeliverPropertyEvent(output->pScreen, (xEvent *) &event); + + RRDestroyOutputProperty(prop); } void RRDeleteAllOutputProperties(RROutputPtr output) { RRPropertyPtr prop, next; - xRROutputPropertyNotifyEvent event; for (prop = output->properties; prop; prop = next) { next = prop->next; - event.type = RREventBase + RRNotify; - event.subCode = RRNotify_OutputProperty; - event.output = output->id; - event.state = PropertyDelete; - event.atom = prop->propertyName; - event.timestamp = currentTime.milliseconds; - RRDeliverEvent(output->pScreen, (xEvent *) &event, - RROutputPropertyNotifyMask); - if (prop->current.data) - xfree(prop->current.data); - if (prop->pending.data) - xfree(prop->pending.data); - xfree(prop); + RRDeleteProperty(output, prop); } } @@ -83,39 +126,17 @@ RRCreateOutputProperty(Atom property) return prop; } -static void -RRDestroyOutputProperty(RRPropertyPtr prop) -{ - if (prop->valid_values) - xfree(prop->valid_values); - if (prop->current.data) - xfree(prop->current.data); - if (prop->pending.data) - xfree(prop->pending.data); - xfree(prop); -} - void RRDeleteOutputProperty(RROutputPtr output, Atom property) { - RRPropertyPtr prop, *prev; - xRROutputPropertyNotifyEvent event; + RRPropertyRec *prop, **prev; for (prev = &output->properties; (prop = *prev); prev = &(prop->next)) - if (prop->propertyName == property) - break; - if (prop) { - *prev = prop->next; - event.type = RREventBase + RRNotify; - event.subCode = RRNotify_OutputProperty; - event.output = output->id; - event.state = PropertyDelete; - event.atom = prop->propertyName; - event.timestamp = currentTime.milliseconds; - RRDeliverEvent(output->pScreen, (xEvent *) &event, - RROutputPropertyNotifyMask); - RRDestroyOutputProperty(prop); - } + if (prop->propertyName == property) { + *prev = prop->next; + RRDeleteProperty(output, prop); + return; + } } int @@ -124,10 +145,8 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type, void *value, Bool sendevent, Bool pending) { RRPropertyPtr prop; - xRROutputPropertyNotifyEvent event; rrScrPrivPtr pScrPriv = rrGetScrPriv(output->pScreen); int size_in_bytes; - int total_size; unsigned long total_len; RRPropertyValuePtr prop_value; RRPropertyValueRec new_value; @@ -140,7 +159,7 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type, if (!prop) { /* just add to list */ prop = RRCreateOutputProperty(property); if (!prop) - return (BadAlloc); + return BadAlloc; add = TRUE; mode = PropModeReplace; } @@ -155,9 +174,9 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type, "PropModeReplace" since they will be written over. */ if ((format != prop_value->format) && (mode != PropModeReplace)) - return (BadMatch); + return BadMatch; if ((prop_value->type != type) && (mode != PropModeReplace)) - return (BadMatch); + return BadMatch; new_value = *prop_value; if (mode == PropModeReplace) total_len = len; @@ -167,9 +186,12 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type, if (mode == PropModeReplace || len > 0) { void *new_data = NULL, *old_data = NULL; - total_size = total_len * size_in_bytes; - new_value.data = (void *) xalloc(total_size); - if (!new_value.data && total_size) { +#ifndef NXAGENT_SERVER + new_value.data = xallocarray(total_len, size_in_bytes); +#else /* !defined(NXAGENT_SERVER) */ + new_value.data = xalloc(total_len * size_in_bytes); +#endif /* !defined(NXAGENT_SERVER) */ + if (!new_value.data && total_len && size_in_bytes) { if (add) RRDestroyOutputProperty(prop); return BadAlloc; @@ -203,12 +225,12 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type, if (pending && pScrPriv->rrOutputSetProperty && !pScrPriv->rrOutputSetProperty(output->pScreen, output, prop->propertyName, &new_value)) { - if (new_value.data) - xfree(new_value.data); - return (BadValue); + xfree(new_value.data); + if (add) + RRDestroyOutputProperty(prop); + return BadValue; } - if (prop_value->data) - xfree(prop_value->data); + xfree(prop_value->data); *prop_value = new_value; } @@ -225,16 +247,17 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type, output->pendingProperties = TRUE; if (sendevent) { - event.type = RREventBase + RRNotify; - event.subCode = RRNotify_OutputProperty; - event.output = output->id; - event.state = PropertyNewValue; - event.atom = prop->propertyName; - event.timestamp = currentTime.milliseconds; - RRDeliverEvent(output->pScreen, (xEvent *) &event, - RROutputPropertyNotifyMask); - } - return (Success); + xRROutputPropertyNotifyEvent event = { + .type = RREventBase + RRNotify, + .subCode = RRNotify_OutputProperty, + .output = output->id, + .state = PropertyNewValue, + .atom = prop->propertyName, + .timestamp = currentTime.milliseconds + }; + RRDeliverPropertyEvent(output->pScreen, (xEvent *) &event); + } + return Success; } Bool @@ -265,7 +288,7 @@ RRPostPendingProperties(RROutputPtr output) pending_value->format == current_value->format && pending_value->size == current_value->size && !memcmp(pending_value->data, current_value->data, - pending_value->size)) + pending_value->size * (pending_value->format / 8))) continue; if (RRChangeOutputProperty(output, property->propertyName, @@ -292,13 +315,21 @@ RRPropertyValuePtr RRGetOutputProperty(RROutputPtr output, Atom property, Bool pending) { RRPropertyPtr prop = RRQueryOutputProperty(output, property); + rrScrPrivPtr pScrPriv = rrGetScrPriv(output->pScreen); if (!prop) return NULL; if (pending && prop->is_pending) return &prop->pending; - else + else { +#if RANDR_13_INTERFACE + /* If we can, try to update the property value first */ + if (pScrPriv->rrOutputGetProperty) + pScrPriv->rrOutputGetProperty(output->pScreen, output, + prop->propertyName); +#endif return &prop->current; + } } int @@ -313,21 +344,31 @@ RRConfigureOutputProperty(RROutputPtr output, Atom property, if (!prop) { prop = RRCreateOutputProperty(property); if (!prop) - return (BadAlloc); + return BadAlloc; add = TRUE; } else if (prop->immutable && !immutable) - return (BadAccess); + return BadAccess; /* * ranges must have even number of values */ - if (range && (num_values & 1)) + if (range && (num_values & 1)) { + if (add) + RRDestroyOutputProperty(prop); return BadMatch; + } +#ifndef NXAGENT_SERVER + new_values = xallocarray(num_values, sizeof(INT32)); +#else /* !defined(NXAGENT_SERVER) */ new_values = xalloc(num_values * sizeof(INT32)); - if (!new_values && num_values) +#endif /* !defined(NXAGENT_SERVER) */ + if (!new_values && num_values) { + if (add) + RRDestroyOutputProperty(prop); return BadAlloc; + } if (num_values) memcpy(new_values, values, num_values * sizeof(INT32)); @@ -336,8 +377,7 @@ RRConfigureOutputProperty(RROutputPtr output, Atom property, * loses any pending values */ if (prop->is_pending && !pending) { - if (prop->pending.data) - xfree(prop->pending.data); + xfree(prop->pending.data); RRInitOutputPropertyValue(&prop->pending); } @@ -345,8 +385,7 @@ RRConfigureOutputProperty(RROutputPtr output, Atom property, prop->range = range; prop->immutable = immutable; prop->num_valid = num_values; - if (prop->valid_values) - xfree(prop->valid_values); + xfree(prop->valid_values); prop->valid_values = new_values; if (add) { @@ -361,47 +400,51 @@ int ProcRRListOutputProperties(ClientPtr client) { REQUEST(xRRListOutputPropertiesReq); - Atom *pAtoms = NULL, *temppAtoms; + Atom *pAtoms = NULL; xRRListOutputPropertiesReply rep; int numProps = 0; RROutputPtr output; RRPropertyPtr prop; + int n; REQUEST_SIZE_MATCH(xRRListOutputPropertiesReq); - output = LookupOutput(client, stuff->output, DixReadAccess); - - if (!output) - return RRErrorBase + BadRROutput; + VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess); for (prop = output->properties; prop; prop = prop->next) numProps++; if (numProps) - if (!(pAtoms = (Atom *) xalloc(numProps * sizeof(Atom)))) - return (BadAlloc); +#ifndef NXAGENT_SERVER + if (!(pAtoms = xallocarray(numProps, sizeof(Atom)))) +#else /* !defined(NXAGENT_SERVER) */ + if (!(pAtoms = xalloc(numProps * sizeof(Atom)))) +#endif /* !defined(NXAGENT_SERVER) */ + return BadAlloc; - rep.type = X_Reply; - rep.length = (numProps * sizeof(Atom)) >> 2; - rep.sequenceNumber = client->sequence; - rep.nAtoms = numProps; + rep = (xRRListOutputPropertiesReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = bytes_to_int32(numProps * sizeof(Atom)), + .nAtoms = numProps + }; if (client->swapped) { - int n; - swaps(&rep.sequenceNumber, n); swapl(&rep.length, n); swaps(&rep.nAtoms, n); } - temppAtoms = pAtoms; - for (prop = output->properties; prop; prop = prop->next) - *temppAtoms++ = prop->propertyName; - WriteToClient(client, sizeof(xRRListOutputPropertiesReply), (char *) &rep); + if (numProps) { + /* Copy property name atoms to reply buffer */ + Atom *temppAtoms = pAtoms; + for (prop = output->properties; prop; prop = prop->next) + *temppAtoms++ = prop->propertyName; + client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms); xfree(pAtoms); } - return (client->noClientException); + return Success; } int @@ -411,33 +454,36 @@ ProcRRQueryOutputProperty(ClientPtr client) xRRQueryOutputPropertyReply rep; RROutputPtr output; RRPropertyPtr prop; - char *extra; + char *extra = NULL; + int n; REQUEST_SIZE_MATCH(xRRQueryOutputPropertyReq); - output = LookupOutput(client, stuff->output, DixReadAccess); - - if (!output) - return RRErrorBase + BadRROutput; + VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess); prop = RRQueryOutputProperty(output, stuff->property); if (!prop) return BadName; if (prop->num_valid) { +#ifndef NXAGENT_SERVER + extra = xallocarray(prop->num_valid, sizeof(INT32)); +#else /* !defined(NXAGENT_SERVER) */ extra = xalloc(prop->num_valid * sizeof(INT32)); +#endif /* !defined(NXAGENT_SERVER) */ if (!extra) return BadAlloc; } - rep.type = X_Reply; - rep.length = prop->num_valid; - rep.sequenceNumber = client->sequence; - rep.pending = prop->is_pending; - rep.range = prop->range; - rep.immutable = prop->immutable; - if (client->swapped) { - int n; + rep = (xRRQueryOutputPropertyReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = prop->num_valid, + .pending = prop->is_pending, + .range = prop->range, + .immutable = prop->immutable + }; + if (client->swapped) { swaps(&rep.sequenceNumber, n); swapl(&rep.length, n); } @@ -449,7 +495,7 @@ ProcRRQueryOutputProperty(ClientPtr client) extra); xfree(extra); } - return (client->noClientException); + return Success; } int @@ -461,15 +507,13 @@ ProcRRConfigureOutputProperty(ClientPtr client) REQUEST_AT_LEAST_SIZE(xRRConfigureOutputPropertyReq); - output = LookupOutput(client, stuff->output, DixReadAccess); - - if (!output) - return RRErrorBase + BadRROutput; + VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess); - num_valid = stuff->length - (sizeof(xRRConfigureOutputPropertyReq) >> 2); - return RRConfigureOutputProperty(output, stuff->property, - stuff->pending, stuff->range, - FALSE, num_valid, (INT32 *) (stuff + 1)); + num_valid = + stuff->length - bytes_to_int32(sizeof(xRRConfigureOutputPropertyReq)); + return RRConfigureOutputProperty(output, stuff->property, stuff->pending, + stuff->range, FALSE, num_valid, + (INT32 *) (stuff + 1)); } int @@ -497,23 +541,21 @@ ProcRRChangeOutputProperty(ClientPtr client) return BadValue; } len = stuff->nUnits; - if (len > ((0xffffffff - sizeof(xChangePropertyReq)) >> 2)) + if (len > bytes_to_int32((0xffffffff - sizeof(xChangePropertyReq)))) return BadLength; sizeInBytes = format >> 3; totalSize = len * sizeInBytes; REQUEST_FIXED_SIZE(xRRChangeOutputPropertyReq, totalSize); - output = LookupOutput(client, stuff->output, DixWriteAccess); - if (!output) - return RRErrorBase + BadRROutput; + VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess); if (!ValidAtom(stuff->property)) { client->errorValue = stuff->property; - return (BadAtom); + return BadAtom; } if (!ValidAtom(stuff->type)) { client->errorValue = stuff->type; - return (BadAtom); + return BadAtom; } err = RRChangeOutputProperty(output, stuff->property, @@ -523,7 +565,7 @@ ProcRRChangeOutputProperty(ClientPtr client) if (err != Success) return err; else - return client->noClientException; + return Success; } int @@ -531,20 +573,30 @@ ProcRRDeleteOutputProperty(ClientPtr client) { REQUEST(xRRDeleteOutputPropertyReq); RROutputPtr output; + RRPropertyPtr prop; REQUEST_SIZE_MATCH(xRRDeleteOutputPropertyReq); UpdateCurrentTime(); - output = LookupOutput(client, stuff->output, DixWriteAccess); - if (!output) - return RRErrorBase + BadRROutput; + VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess); if (!ValidAtom(stuff->property)) { client->errorValue = stuff->property; - return (BadAtom); + return BadAtom; + } + + prop = RRQueryOutputProperty(output, stuff->property); + if (!prop) { + client->errorValue = stuff->property; + return BadName; + } + + if (prop->immutable) { + client->errorValue = stuff->property; + return BadAccess; } RRDeleteOutputProperty(output, stuff->property); - return client->noClientException; + return Success; } int @@ -556,35 +608,36 @@ ProcRRGetOutputProperty(ClientPtr client) unsigned long n, len, ind; RROutputPtr output; xRRGetOutputPropertyReply reply; - char *extra; + char *extra = NULL; + int m; REQUEST_SIZE_MATCH(xRRGetOutputPropertyReq); if (stuff->delete) UpdateCurrentTime(); - output = LookupOutput(client, stuff->output, - stuff->delete ? DixWriteAccess : DixReadAccess); - if (!output) - return RRErrorBase + BadRROutput; + VERIFY_RR_OUTPUT(stuff->output, output, + stuff->delete ? DixWriteAccess : DixReadAccess); if (!ValidAtom(stuff->property)) { client->errorValue = stuff->property; - return (BadAtom); + return BadAtom; } if ((stuff->delete != xTrue) && (stuff->delete != xFalse)) { client->errorValue = stuff->delete; - return (BadValue); + return BadValue; } if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type)) { client->errorValue = stuff->type; - return (BadAtom); + return BadAtom; } for (prev = &output->properties; (prop = *prev); prev = &prop->next) if (prop->propertyName == stuff->property) break; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; + reply = (xRRGetOutputPropertyReply) { + .type = X_Reply, + .sequenceNumber = client->sequence + }; if (!prop) { reply.nItems = 0; reply.length = 0; @@ -592,25 +645,23 @@ ProcRRGetOutputProperty(ClientPtr client) reply.propertyType = None; reply.format = 0; if (client->swapped) { - int n; - - swaps(&reply.sequenceNumber, n); - swapl(&reply.length, n); - swapl(&reply.propertyType, n); - swapl(&reply.bytesAfter, n); - swapl(&reply.nItems, n); + swaps(&reply.sequenceNumber, m); + swapl(&reply.length, m); + swapl(&reply.propertyType, m); + swapl(&reply.bytesAfter, m); + swapl(&reply.nItems, m); } - WriteToClient(client, sizeof(xRRGetOutputPropertyReply), &reply); - return (client->noClientException); + WriteToClient(client, sizeof(xRRGetOutputPropertyReply), + (char *) &reply); + return Success; } if (prop->immutable && stuff->delete) return BadAccess; - if (stuff->pending && prop->is_pending) - prop_value = &prop->pending; - else - prop_value = &prop->current; + prop_value = RRGetOutputProperty(output, stuff->property, stuff->pending); + if (!prop_value) + return BadAtom; /* If the request type and actual type don't match. Return the property information, but not the data. */ @@ -623,16 +674,15 @@ ProcRRGetOutputProperty(ClientPtr client) reply.nItems = 0; reply.propertyType = prop_value->type; if (client->swapped) { - int n; - swaps(&reply.sequenceNumber, n); swapl(&reply.length, n); swapl(&reply.propertyType, n); swapl(&reply.bytesAfter, n); swapl(&reply.nItems, n); } - WriteToClient(client, sizeof(xRRGetOutputPropertyReply), &reply); - return (client->noClientException); + WriteToClient(client, sizeof(xRRGetOutputPropertyReply), + (char *) &reply); + return Success; } /* @@ -658,7 +708,7 @@ ProcRRGetOutputProperty(ClientPtr client) } reply.bytesAfter = n - (ind + len); reply.format = prop_value->format; - reply.length = (len + 3) >> 2; + reply.length = bytes_to_int32(len); if (prop_value->format) reply.nItems = len / (prop_value->format / 8); else @@ -666,28 +716,25 @@ ProcRRGetOutputProperty(ClientPtr client) reply.propertyType = prop_value->type; if (stuff->delete && (reply.bytesAfter == 0)) { - xRROutputPropertyNotifyEvent event; - - event.type = RREventBase + RRNotify; - event.subCode = RRNotify_OutputProperty; - event.output = output->id; - event.state = PropertyDelete; - event.atom = prop->propertyName; - event.timestamp = currentTime.milliseconds; - RRDeliverEvent(output->pScreen, (xEvent *) &event, - RROutputPropertyNotifyMask); + xRROutputPropertyNotifyEvent event = { + .type = RREventBase + RRNotify, + .subCode = RRNotify_OutputProperty, + .output = output->id, + .state = PropertyDelete, + .atom = prop->propertyName, + .timestamp = currentTime.milliseconds + }; + RRDeliverPropertyEvent(output->pScreen, (xEvent *) &event); } if (client->swapped) { - int n; - swaps(&reply.sequenceNumber, n); swapl(&reply.length, n); swapl(&reply.propertyType, n); swapl(&reply.bytesAfter, n); swapl(&reply.nItems, n); } - WriteToClient(client, sizeof(xGenericReply), &reply); + WriteToClient(client, sizeof(xGenericReply), (char *) &reply); if (len) { memcpy(extra, (char *) prop_value->data + ind, len); switch (reply.format) { @@ -709,5 +756,5 @@ ProcRRGetOutputProperty(ClientPtr client) *prev = prop->next; RRDestroyOutputProperty(prop); } - return (client->noClientException); + return Success; } diff --git a/nx-X11/programs/Xserver/randr/rrprovider.c b/nx-X11/programs/Xserver/randr/rrprovider.c new file mode 100644 index 000000000..b2251b682 --- /dev/null +++ b/nx-X11/programs/Xserver/randr/rrprovider.c @@ -0,0 +1,484 @@ +/* + * Copyright © 2012 Red Hat Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + * + * Authors: Dave Airlie + */ + +#include "randrstr.h" +#include "swaprep.h" + +RESTYPE RRProviderType; + +/* + * Initialize provider type error value + */ +void +RRProviderInitErrorValue(void) +{ +#ifndef NXAGENT_SERVER + SetResourceTypeErrorValue(RRProviderType, RRErrorBase + BadRRProvider); +#endif +} + +#define ADD_PROVIDER(_pScreen) do { \ + pScrPriv = rrGetScrPriv((_pScreen)); \ + if (pScrPriv->provider) { \ + providers[count_providers] = pScrPriv->provider->id; \ + if (client->swapped) \ + swapl(&providers[count_providers], n); \ + count_providers++; \ + } \ + } while(0) + +int +ProcRRGetProviders(ClientPtr client) +{ + REQUEST(xRRGetProvidersReq); + xRRGetProvidersReply rep; + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + int rc; + CARD8 *extra; + unsigned int extraLen; + RRProvider *providers; + int total_providers = 0, count_providers = 0; +#ifndef NXAGENT_SERVER + ScreenPtr iter; +#endif + int n; + + REQUEST_SIZE_MATCH(xRRGetProvidersReq); +#ifndef NXAGENT_SERVER + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); +#else + pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess); + rc = pWin ? Success : BadWindow; +#endif + + if (rc != Success) + return rc; + + pScreen = pWin->drawable.pScreen; + + pScrPriv = rrGetScrPriv(pScreen); + + if (pScrPriv->provider) + total_providers++; +#ifndef NXAGENT_SERVER + xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) { + pScrPriv = rrGetScrPriv(iter); + total_providers += pScrPriv->provider ? 1 : 0; + } + xorg_list_for_each_entry(iter, &pScreen->offload_slave_list, offload_head) { + pScrPriv = rrGetScrPriv(iter); + total_providers += pScrPriv->provider ? 1 : 0; + } + xorg_list_for_each_entry(iter, &pScreen->unattached_list, unattached_head) { + pScrPriv = rrGetScrPriv(iter); + total_providers += pScrPriv->provider ? 1 : 0; + } +#endif + + pScrPriv = rrGetScrPriv(pScreen); + + if (!pScrPriv) + { + rep = (xRRGetProvidersReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0, + .timestamp = currentTime.milliseconds, + .nProviders = 0 + }; + extra = NULL; + extraLen = 0; + } else { + rep = (xRRGetProvidersReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .timestamp = pScrPriv->lastSetTime.milliseconds, + .nProviders = total_providers, + .length = total_providers + }; + extraLen = rep.length << 2; + if (extraLen) { + extra = xalloc(extraLen); + if (!extra) + return BadAlloc; + } else + extra = NULL; + + providers = (RRProvider *) extra; + ADD_PROVIDER(pScreen); +#ifndef NXAGENT_SERVER + xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) { + ADD_PROVIDER(iter); + } + xorg_list_for_each_entry(iter, &pScreen->offload_slave_list, offload_head) { + ADD_PROVIDER(iter); + } + xorg_list_for_each_entry(iter, &pScreen->unattached_list, unattached_head) { + ADD_PROVIDER(iter); + } +#endif + } + + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.timestamp, n); + swaps(&rep.nProviders, n); + } + WriteToClient(client, sizeof(xRRGetProvidersReply), (char *) &rep); + if (extraLen) + { + WriteToClient(client, extraLen, (char *) extra); + xfree(extra); + } + return Success; +} + +int +ProcRRGetProviderInfo(ClientPtr client) +{ + REQUEST(xRRGetProviderInfoReq); + xRRGetProviderInfoReply rep; + rrScrPrivPtr pScrPriv; +#ifndef NXAGENT_SERVER + rrScrPrivPtr pScrProvPriv; +#endif + RRProviderPtr provider; + ScreenPtr pScreen; + CARD8 *extra; + unsigned int extraLen = 0; + RRCrtc *crtcs; + RROutput *outputs; + int i; + char *name; +#ifndef NXAGENT_SERVER + ScreenPtr provscreen; +#endif + RRProvider *providers; + uint32_t *prov_cap; + int n; + + REQUEST_SIZE_MATCH(xRRGetProviderInfoReq); + VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess); + + pScreen = provider->pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + rep = (xRRGetProviderInfoReply) { + .type = X_Reply, + .status = RRSetConfigSuccess, + .sequenceNumber = client->sequence, + .length = 0, + .capabilities = provider->capabilities, + .nameLength = provider->nameLength, + .timestamp = pScrPriv->lastSetTime.milliseconds, + .nCrtcs = pScrPriv->numCrtcs, + .nOutputs = pScrPriv->numOutputs, + .nAssociatedProviders = 0 + }; + + /* count associated providers */ + if (provider->offload_sink) + rep.nAssociatedProviders++; + if (provider->output_source) + rep.nAssociatedProviders++; +#ifndef NXAGENT_SERVER + xorg_list_for_each_entry(provscreen, &pScreen->output_slave_list, output_head) + rep.nAssociatedProviders++; + xorg_list_for_each_entry(provscreen, &pScreen->offload_slave_list, offload_head) + rep.nAssociatedProviders++; +#endif + + rep.length = (pScrPriv->numCrtcs + pScrPriv->numOutputs + + (rep.nAssociatedProviders * 2) + bytes_to_int32(rep.nameLength)); + + extraLen = rep.length << 2; + if (extraLen) { + extra = xalloc(extraLen); + if (!extra) + return BadAlloc; + } + else + extra = NULL; + + crtcs = (RRCrtc *) extra; + outputs = (RROutput *) (crtcs + rep.nCrtcs); + providers = (RRProvider *) (outputs + rep.nOutputs); + prov_cap = (unsigned int *) (providers + rep.nAssociatedProviders); + name = (char *) (prov_cap + rep.nAssociatedProviders); + + for (i = 0; i < pScrPriv->numCrtcs; i++) { + crtcs[i] = pScrPriv->crtcs[i]->id; + if (client->swapped) + swapl(&crtcs[i], n); + } + + for (i = 0; i < pScrPriv->numOutputs; i++) { + outputs[i] = pScrPriv->outputs[i]->id; + if (client->swapped) + swapl(&outputs[i], n); + } + + i = 0; + if (provider->offload_sink) { + providers[i] = provider->offload_sink->id; + if (client->swapped) + swapl(&providers[i], n); + prov_cap[i] = RR_Capability_SinkOffload; + if (client->swapped) + swapl(&prov_cap[i], n); + i++; + } + if (provider->output_source) { + providers[i] = provider->output_source->id; + if (client->swapped) + swapl(&providers[i], n); + prov_cap[i] = RR_Capability_SourceOutput; + swapl(&prov_cap[i], n); + i++; + } +#ifndef NXAGENT_SERVER + xorg_list_for_each_entry(provscreen, &pScreen->output_slave_list, output_head) { + pScrProvPriv = rrGetScrPriv(provscreen); + providers[i] = pScrProvPriv->provider->id; + if (client->swapped) + swapl(&providers[i]); + prov_cap[i] = RR_Capability_SinkOutput; + if (client->swapped) + swapl(&prov_cap[i]); + i++; + } + xorg_list_for_each_entry(provscreen, &pScreen->offload_slave_list, offload_head) { + pScrProvPriv = rrGetScrPriv(provscreen); + providers[i] = pScrProvPriv->provider->id; + if (client->swapped) + swapl(&providers[i]); + prov_cap[i] = RR_Capability_SourceOffload; + if (client->swapped) + swapl(&prov_cap[i]); + i++; + } +#endif + memcpy(name, provider->name, rep.nameLength); + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.capabilities, n); + swaps(&rep.nCrtcs, n); + swaps(&rep.nOutputs, n); + swaps(&rep.nameLength, n); + } + WriteToClient(client, sizeof(xRRGetProviderInfoReply), (char *) &rep); + if (extraLen) + { + WriteToClient(client, extraLen, (char *) extra); + xfree(extra); + } + return Success; +} + +int +ProcRRSetProviderOutputSource(ClientPtr client) +{ + REQUEST(xRRSetProviderOutputSourceReq); + rrScrPrivPtr pScrPriv; + RRProviderPtr provider, source_provider = NULL; + ScreenPtr pScreen; + + REQUEST_SIZE_MATCH(xRRSetProviderOutputSourceReq); + + VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess); + + if (!(provider->capabilities & RR_Capability_SinkOutput)) + return BadValue; + + if (stuff->source_provider) { + VERIFY_RR_PROVIDER(stuff->source_provider, source_provider, DixReadAccess); + + if (!(source_provider->capabilities & RR_Capability_SourceOutput)) + return BadValue; + } + + pScreen = provider->pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + pScrPriv->rrProviderSetOutputSource(pScreen, provider, source_provider); + + provider->changed = TRUE; + RRSetChanged(pScreen); + + RRTellChanged(pScreen); + + return Success; +} + +int +ProcRRSetProviderOffloadSink(ClientPtr client) +{ + REQUEST(xRRSetProviderOffloadSinkReq); + rrScrPrivPtr pScrPriv; + RRProviderPtr provider, sink_provider = NULL; + ScreenPtr pScreen; + + REQUEST_SIZE_MATCH(xRRSetProviderOffloadSinkReq); + + VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess); + if (!(provider->capabilities & RR_Capability_SourceOffload)) + return BadValue; +#ifndef NXAGENT_SERVER + if (!provider->pScreen->isGPU) + return BadValue; +#endif /* !defined(NXAGENT_SERVER) */ + + if (stuff->sink_provider) { + VERIFY_RR_PROVIDER(stuff->sink_provider, sink_provider, DixReadAccess); + if (!(sink_provider->capabilities & RR_Capability_SinkOffload)) + return BadValue; + } + pScreen = provider->pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + pScrPriv->rrProviderSetOffloadSink(pScreen, provider, sink_provider); + + provider->changed = TRUE; + RRSetChanged(pScreen); + + RRTellChanged(pScreen); + + return Success; +} + +RRProviderPtr +RRProviderCreate(ScreenPtr pScreen, const char *name, + int nameLength) +{ + RRProviderPtr provider; + rrScrPrivPtr pScrPriv; + + pScrPriv = rrGetScrPriv(pScreen); + + provider = xcalloc(1, sizeof(RRProviderRec) + nameLength + 1); + if (!provider) + return NULL; + + provider->id = FakeClientID(0); + provider->pScreen = pScreen; + provider->name = (char *) (provider + 1); + provider->nameLength = nameLength; + memcpy(provider->name, name, nameLength); + provider->name[nameLength] = '\0'; + provider->changed = FALSE; + + if (!AddResource(provider->id, RRProviderType, (void *) provider)) + return NULL; + pScrPriv->provider = provider; + return provider; +} + +/* + * Destroy a provider at shutdown + */ +void +RRProviderDestroy(RRProviderPtr provider) +{ + FreeResource(provider->id, 0); +} + +void +RRProviderSetCapabilities(RRProviderPtr provider, uint32_t capabilities) +{ + provider->capabilities = capabilities; +} + +static int +RRProviderDestroyResource(void *value, XID pid) +{ + RRProviderPtr provider = (RRProviderPtr) value; + ScreenPtr pScreen = provider->pScreen; + + if (pScreen) + { + rrScrPriv(pScreen); + + if (pScrPriv->rrProviderDestroy) + (*pScrPriv->rrProviderDestroy) (pScreen, provider); + pScrPriv->provider = NULL; + } + xfree(provider); + return 1; +} + +Bool +RRProviderInit(void) +{ + RRProviderType = CreateNewResourceType(RRProviderDestroyResource +#ifndef NXAGENT_SERVER + , "Provider" +#endif /* !defined(NXAGENT_SERVER) */ + ); + if (!RRProviderType) + return FALSE; + + return TRUE; +} + +extern _X_EXPORT Bool +RRProviderLookup(XID id, RRProviderPtr * provider_p) +{ +#ifndef NXAGENT_SERVER + int rc = dixLookupResourceByType((void **) provider_p, id, + RRProviderType, NullClient, DixReadAccess); + if (rc == Success) + return TRUE; +#else /* !defined(NXAGENT_SERVER) */ + provider_p = (RRProviderPtr *) LookupIDByType(id, RREventType); + if (provider_p) + return TRUE; +#endif /* !defined(NXAGENT_SERVER) */ + + return FALSE; +} + +void +RRDeliverProviderEvent(ClientPtr client, WindowPtr pWin, RRProviderPtr provider) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + + rrScrPriv(pScreen); + + xRRProviderChangeNotifyEvent pe = { + .type = RRNotify + RREventBase, + .subCode = RRNotify_ProviderChange, +#ifdef NXAGENT_SERVER + .sequenceNumber = client->sequence, +#endif + .timestamp = pScrPriv->lastSetTime.milliseconds, + .window = pWin->drawable.id, + .provider = provider->id + }; + + WriteEventsToClient(client, 1, (xEvent *) &pe); +} diff --git a/nx-X11/programs/Xserver/randr/rrproviderproperty.c b/nx-X11/programs/Xserver/randr/rrproviderproperty.c new file mode 100644 index 000000000..a68a94ff2 --- /dev/null +++ b/nx-X11/programs/Xserver/randr/rrproviderproperty.c @@ -0,0 +1,752 @@ +/* + * Copyright © 2006 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "randrstr.h" +#include "propertyst.h" +#include "swaprep.h" + +static int +DeliverPropertyEvent(WindowPtr pWin, void *value) +{ + xRRProviderPropertyNotifyEvent *event = value; + RREventPtr *pHead, pRREvent; + +#ifndef NXAGENT_SERVER + dixLookupResourceByType((void **) &pHead, pWin->drawable.id, + RREventType, serverClient, DixReadAccess); +#else /* !defined(NXAGENT_SERVER) */ + pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, RREventType); +#endif /* !defined(NXAGENT_SERVER) */ + if (!pHead) + return WT_WALKCHILDREN; + + for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) { + if (!(pRREvent->mask & RRProviderPropertyNotifyMask)) + continue; + + event->window = pRREvent->window->drawable.id; + WriteEventsToClient(pRREvent->client, 1, (xEvent *) event); + } + + return WT_WALKCHILDREN; +} + +static void +RRDeliverPropertyEvent(ScreenPtr pScreen, xEvent *event) +{ + if (!(dispatchException & (DE_RESET | DE_TERMINATE))) + WalkTree(pScreen, DeliverPropertyEvent, event); +} + +static void +RRDestroyProviderProperty(RRPropertyPtr prop) +{ + xfree(prop->valid_values); + xfree(prop->current.data); + xfree(prop->pending.data); + xfree(prop); +} + +static void +RRDeleteProperty(RRProviderRec * provider, RRPropertyRec * prop) +{ + xRRProviderPropertyNotifyEvent event = { + .type = RREventBase + RRNotify, + .subCode = RRNotify_ProviderProperty, + .provider = provider->id, + .state = PropertyDelete, + .atom = prop->propertyName, + .timestamp = currentTime.milliseconds + }; + + RRDeliverPropertyEvent(provider->pScreen, (xEvent *) &event); + + RRDestroyProviderProperty(prop); +} + +void +RRDeleteAllProviderProperties(RRProviderPtr provider) +{ + RRPropertyPtr prop, next; + + for (prop = provider->properties; prop; prop = next) { + next = prop->next; + RRDeleteProperty(provider, prop); + } +} + +static void +RRInitProviderPropertyValue(RRPropertyValuePtr property_value) +{ + property_value->type = None; + property_value->format = 0; + property_value->size = 0; + property_value->data = NULL; +} + +static RRPropertyPtr +RRCreateProviderProperty(Atom property) +{ + RRPropertyPtr prop; + + prop = (RRPropertyPtr) xalloc(sizeof(RRPropertyRec)); + if (!prop) + return NULL; + prop->next = NULL; + prop->propertyName = property; + prop->is_pending = FALSE; + prop->range = FALSE; + prop->immutable = FALSE; + prop->num_valid = 0; + prop->valid_values = NULL; + RRInitProviderPropertyValue(&prop->current); + RRInitProviderPropertyValue(&prop->pending); + return prop; +} + +void +RRDeleteProviderProperty(RRProviderPtr provider, Atom property) +{ + RRPropertyRec *prop, **prev; + + for (prev = &provider->properties; (prop = *prev); prev = &(prop->next)) + if (prop->propertyName == property) { + *prev = prop->next; + RRDeleteProperty(provider, prop); + return; + } +} + +int +RRChangeProviderProperty(RRProviderPtr provider, Atom property, Atom type, + int format, int mode, unsigned long len, + void *value, Bool sendevent, Bool pending) +{ + RRPropertyPtr prop; + rrScrPrivPtr pScrPriv = rrGetScrPriv(provider->pScreen); + int size_in_bytes; + int total_size; + unsigned long total_len; + RRPropertyValuePtr prop_value; + RRPropertyValueRec new_value; + Bool add = FALSE; + + size_in_bytes = format >> 3; + + /* first see if property already exists */ + prop = RRQueryProviderProperty(provider, property); + if (!prop) { /* just add to list */ + prop = RRCreateProviderProperty(property); + if (!prop) + return BadAlloc; + add = TRUE; + mode = PropModeReplace; + } + if (pending && prop->is_pending) + prop_value = &prop->pending; + else + prop_value = &prop->current; + + /* To append or prepend to a property the request format and type + must match those of the already defined property. The + existing format and type are irrelevant when using the mode + "PropModeReplace" since they will be written over. */ + + if ((format != prop_value->format) && (mode != PropModeReplace)) + return BadMatch; + if ((prop_value->type != type) && (mode != PropModeReplace)) + return BadMatch; + new_value = *prop_value; + if (mode == PropModeReplace) + total_len = len; + else + total_len = prop_value->size + len; + + if (mode == PropModeReplace || len > 0) { + void *new_data = NULL, *old_data = NULL; + + total_size = total_len * size_in_bytes; + new_value.data = (void *) xalloc(total_size); + if (!new_value.data && total_size) { + if (add) + RRDestroyProviderProperty(prop); + return BadAlloc; + } + new_value.size = len; + new_value.type = type; + new_value.format = format; + + switch (mode) { + case PropModeReplace: + new_data = new_value.data; + old_data = NULL; + break; + case PropModeAppend: + new_data = (void *) (((char *) new_value.data) + + (prop_value->size * size_in_bytes)); + old_data = new_value.data; + break; + case PropModePrepend: + new_data = new_value.data; + old_data = (void *) (((char *) new_value.data) + + (prop_value->size * size_in_bytes)); + break; + } + if (new_data) + memcpy((char *) new_data, (char *) value, len * size_in_bytes); + if (old_data) + memcpy((char *) old_data, (char *) prop_value->data, + prop_value->size * size_in_bytes); + + if (pending && pScrPriv->rrProviderSetProperty && + !pScrPriv->rrProviderSetProperty(provider->pScreen, provider, + prop->propertyName, &new_value)) { + if (add) + RRDestroyProviderProperty(prop); + xfree(new_value.data); + return BadValue; + } + xfree(prop_value->data); + *prop_value = new_value; + } + + else if (len == 0) { + /* do nothing */ + } + + if (add) { + prop->next = provider->properties; + provider->properties = prop; + } + + if (pending && prop->is_pending) + provider->pendingProperties = TRUE; + + if (sendevent) { + xRRProviderPropertyNotifyEvent event = { + .type = RREventBase + RRNotify, + .subCode = RRNotify_ProviderProperty, + .provider = provider->id, + .state = PropertyNewValue, + .atom = prop->propertyName, + .timestamp = currentTime.milliseconds + }; + RRDeliverPropertyEvent(provider->pScreen, (xEvent *) &event); + } + return Success; +} + +Bool +RRPostProviderPendingProperties(RRProviderPtr provider) +{ + RRPropertyValuePtr pending_value; + RRPropertyValuePtr current_value; + RRPropertyPtr property; + Bool ret = TRUE; + + if (!provider->pendingProperties) + return TRUE; + + provider->pendingProperties = FALSE; + for (property = provider->properties; property; property = property->next) { + /* Skip non-pending properties */ + if (!property->is_pending) + continue; + + pending_value = &property->pending; + current_value = &property->current; + + /* + * If the pending and current values are equal, don't mark it + * as changed (which would deliver an event) + */ + if (pending_value->type == current_value->type && + pending_value->format == current_value->format && + pending_value->size == current_value->size && + !memcmp(pending_value->data, current_value->data, + pending_value->size * (pending_value->format / 8))) + continue; + + if (RRChangeProviderProperty(provider, property->propertyName, + pending_value->type, pending_value->format, + PropModeReplace, pending_value->size, + pending_value->data, TRUE, FALSE) != Success) + ret = FALSE; + } + return ret; +} + +RRPropertyPtr +RRQueryProviderProperty(RRProviderPtr provider, Atom property) +{ + RRPropertyPtr prop; + + for (prop = provider->properties; prop; prop = prop->next) + if (prop->propertyName == property) + return prop; + return NULL; +} + +RRPropertyValuePtr +RRGetProviderProperty(RRProviderPtr provider, Atom property, Bool pending) +{ + RRPropertyPtr prop = RRQueryProviderProperty(provider, property); + rrScrPrivPtr pScrPriv = rrGetScrPriv(provider->pScreen); + + if (!prop) + return NULL; + if (pending && prop->is_pending) + return &prop->pending; + else { +#if RANDR_13_INTERFACE + /* If we can, try to update the property value first */ + if (pScrPriv->rrProviderGetProperty) + pScrPriv->rrProviderGetProperty(provider->pScreen, provider, + prop->propertyName); +#endif + return &prop->current; + } +} + +int +RRConfigureProviderProperty(RRProviderPtr provider, Atom property, + Bool pending, Bool range, Bool immutable, + int num_values, INT32 *values) +{ + RRPropertyPtr prop = RRQueryProviderProperty(provider, property); + Bool add = FALSE; + INT32 *new_values; + + if (!prop) { + prop = RRCreateProviderProperty(property); + if (!prop) + return BadAlloc; + add = TRUE; + } + else if (prop->immutable && !immutable) + return BadAccess; + + /* + * ranges must have even number of values + */ + if (range && (num_values & 1)) { + if (add) + RRDestroyProviderProperty(prop); + return BadMatch; + } + +#ifndef NXAGENT_SERVER + new_values = xallocarray(num_values, sizeof(INT32)); +#else /* !defined(NXAGENT_SERVER) */ + new_values = xalloc(num_values * sizeof(INT32)); +#endif /* !defined(NXAGENT_SERVER) */ + + if (!new_values && num_values) { + if (add) + RRDestroyProviderProperty(prop); + return BadAlloc; + } + if (num_values) + memcpy(new_values, values, num_values * sizeof(INT32)); + + /* + * Property moving from pending to non-pending + * loses any pending values + */ + if (prop->is_pending && !pending) { + xfree(prop->pending.data); + RRInitProviderPropertyValue(&prop->pending); + } + + prop->is_pending = pending; + prop->range = range; + prop->immutable = immutable; + prop->num_valid = num_values; + xfree(prop->valid_values); + prop->valid_values = new_values; + + if (add) { + prop->next = provider->properties; + provider->properties = prop; + } + + return Success; +} + +int +ProcRRListProviderProperties(ClientPtr client) +{ + REQUEST(xRRListProviderPropertiesReq); + Atom *pAtoms = NULL, *temppAtoms; + xRRListProviderPropertiesReply rep; + int numProps = 0; + RRProviderPtr provider; + RRPropertyPtr prop; + int n; + + REQUEST_SIZE_MATCH(xRRListProviderPropertiesReq); + + VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess); + + for (prop = provider->properties; prop; prop = prop->next) + numProps++; + if (numProps) +#ifndef NXAGENT_SERVER + if (!(pAtoms = xallocarray(numProps, sizeof(Atom)))) +#else /* !defined(NXAGENT_SERVER) */ + if (!(pAtoms = xalloc(numProps * sizeof(Atom)))) +#endif /* !defined(NXAGENT_SERVER) */ + return BadAlloc; + + rep = (xRRListProviderPropertiesReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = bytes_to_int32(numProps * sizeof(Atom)), + .nAtoms = numProps + }; + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.nAtoms, n); + } + temppAtoms = pAtoms; + for (prop = provider->properties; prop; prop = prop->next) + *temppAtoms++ = prop->propertyName; + + WriteToClient(client, sizeof(xRRListProviderPropertiesReply), + (char *) &rep); + if (numProps) { + client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; + WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms); + xfree(pAtoms); + } + return Success; +} + +int +ProcRRQueryProviderProperty(ClientPtr client) +{ + REQUEST(xRRQueryProviderPropertyReq); + xRRQueryProviderPropertyReply rep; + RRProviderPtr provider; + RRPropertyPtr prop; + char *extra = NULL; + int n; + + REQUEST_SIZE_MATCH(xRRQueryProviderPropertyReq); + + VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess); + + prop = RRQueryProviderProperty(provider, stuff->property); + if (!prop) + return BadName; + + if (prop->num_valid) { +#ifndef NXAGENT_SERVER + extra = xallocarray(prop->num_valid, sizeof(INT32)); +#else /* !defined(NXAGENT_SERVER) */ + extra = xalloc(prop->num_valid * sizeof(INT32)); +#endif /* !defined(NXAGENT_SERVER) */ + if (!extra) + return BadAlloc; + } + rep = (xRRQueryProviderPropertyReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = prop->num_valid, + .pending = prop->is_pending, + .range = prop->range, + .immutable = prop->immutable + }; + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + } + WriteToClient(client, sizeof(xRRQueryProviderPropertyReply), (char *) &rep); + if (prop->num_valid) { + memcpy(extra, prop->valid_values, prop->num_valid * sizeof(INT32)); + client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; + WriteSwappedDataToClient(client, prop->num_valid * sizeof(INT32), + extra); + xfree(extra); + } + return Success; +} + +int +ProcRRConfigureProviderProperty(ClientPtr client) +{ + REQUEST(xRRConfigureProviderPropertyReq); + RRProviderPtr provider; + int num_valid; + + REQUEST_AT_LEAST_SIZE(xRRConfigureProviderPropertyReq); + + VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess); + + num_valid = + stuff->length - bytes_to_int32(sizeof(xRRConfigureProviderPropertyReq)); + return RRConfigureProviderProperty(provider, stuff->property, stuff->pending, + stuff->range, FALSE, num_valid, + (INT32 *) (stuff + 1)); +} + +int +ProcRRChangeProviderProperty(ClientPtr client) +{ + REQUEST(xRRChangeProviderPropertyReq); + RRProviderPtr provider; + char format, mode; + unsigned long len; + int sizeInBytes; + int totalSize; + int err; + + REQUEST_AT_LEAST_SIZE(xRRChangeProviderPropertyReq); + UpdateCurrentTime(); + format = stuff->format; + mode = stuff->mode; + if ((mode != PropModeReplace) && (mode != PropModeAppend) && + (mode != PropModePrepend)) { + client->errorValue = mode; + return BadValue; + } + if ((format != 8) && (format != 16) && (format != 32)) { + client->errorValue = format; + return BadValue; + } + len = stuff->nUnits; + if (len > bytes_to_int32((0xffffffff - sizeof(xChangePropertyReq)))) + return BadLength; + sizeInBytes = format >> 3; + totalSize = len * sizeInBytes; + REQUEST_FIXED_SIZE(xRRChangeProviderPropertyReq, totalSize); + + VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess); + + if (!ValidAtom(stuff->property)) { + client->errorValue = stuff->property; + return BadAtom; + } + if (!ValidAtom(stuff->type)) { + client->errorValue = stuff->type; + return BadAtom; + } + + err = RRChangeProviderProperty(provider, stuff->property, + stuff->type, (int) format, + (int) mode, len, (void *) &stuff[1], TRUE, + TRUE); + if (err != Success) + return err; + else + return Success; +} + +int +ProcRRDeleteProviderProperty(ClientPtr client) +{ + REQUEST(xRRDeleteProviderPropertyReq); + RRProviderPtr provider; + RRPropertyPtr prop; + + REQUEST_SIZE_MATCH(xRRDeleteProviderPropertyReq); + UpdateCurrentTime(); + VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess); + + if (!ValidAtom(stuff->property)) { + client->errorValue = stuff->property; + return BadAtom; + } + + prop = RRQueryProviderProperty(provider, stuff->property); + if (!prop) { + client->errorValue = stuff->property; + return BadName; + } + + if (prop->immutable) { + client->errorValue = stuff->property; + return BadAccess; + } + + RRDeleteProviderProperty(provider, stuff->property); + return Success; +} + +int +ProcRRGetProviderProperty(ClientPtr client) +{ + REQUEST(xRRGetProviderPropertyReq); + RRPropertyPtr prop, *prev; + RRPropertyValuePtr prop_value; + unsigned long n, len, ind; + RRProviderPtr provider; + xRRGetProviderPropertyReply reply = { + .type = X_Reply, + .sequenceNumber = client->sequence + }; + char *extra = NULL; + + REQUEST_SIZE_MATCH(xRRGetProviderPropertyReq); + if (stuff->delete) + UpdateCurrentTime(); + VERIFY_RR_PROVIDER(stuff->provider, provider, + stuff->delete ? DixWriteAccess : DixReadAccess); + + if (!ValidAtom(stuff->property)) { + client->errorValue = stuff->property; + return BadAtom; + } + if ((stuff->delete != xTrue) && (stuff->delete != xFalse)) { + client->errorValue = stuff->delete; + return BadValue; + } + if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type)) { + client->errorValue = stuff->type; + return BadAtom; + } + + for (prev = &provider->properties; (prop = *prev); prev = &prop->next) + if (prop->propertyName == stuff->property) + break; + + if (!prop) { + reply.nItems = 0; + reply.length = 0; + reply.bytesAfter = 0; + reply.propertyType = None; + reply.format = 0; + if (client->swapped) { + swaps(&reply.sequenceNumber, n); + swapl(&reply.length, n); + swapl(&reply.propertyType, n); + swapl(&reply.bytesAfter, n); + swapl(&reply.nItems, n); + } + WriteToClient(client, sizeof(xRRGetProviderPropertyReply), + (char *) &reply); + return Success; + } + + if (prop->immutable && stuff->delete) + return BadAccess; + + prop_value = RRGetProviderProperty(provider, stuff->property, stuff->pending); + if (!prop_value) + return BadAtom; + + /* If the request type and actual type don't match. Return the + property information, but not the data. */ + + if (((stuff->type != prop_value->type) && (stuff->type != AnyPropertyType)) + ) { + reply.bytesAfter = prop_value->size; + reply.format = prop_value->format; + reply.length = 0; + reply.nItems = 0; + reply.propertyType = prop_value->type; + if (client->swapped) { + swaps(&reply.sequenceNumber, n); + swapl(&reply.length, n); + swapl(&reply.propertyType, n); + swapl(&reply.bytesAfter, n); + swapl(&reply.nItems, n); + } + WriteToClient(client, sizeof(xRRGetProviderPropertyReply), + (char *) &reply); + return Success; + } + +/* + * Return type, format, value to client + */ + n = (prop_value->format / 8) * prop_value->size; /* size (bytes) of prop */ + ind = stuff->longOffset << 2; + + /* If longOffset is invalid such that it causes "len" to + be negative, it's a value error. */ + + if (n < ind) { + client->errorValue = stuff->longOffset; + return BadValue; + } + + len = min(n - ind, 4 * stuff->longLength); + + if (len) { + extra = xalloc(len); + if (!extra) + return BadAlloc; + } + reply.bytesAfter = n - (ind + len); + reply.format = prop_value->format; + reply.length = bytes_to_int32(len); + if (prop_value->format) + reply.nItems = len / (prop_value->format / 8); + else + reply.nItems = 0; + reply.propertyType = prop_value->type; + + if (stuff->delete && (reply.bytesAfter == 0)) { + xRRProviderPropertyNotifyEvent event = { + .type = RREventBase + RRNotify, + .subCode = RRNotify_ProviderProperty, + .provider = provider->id, + .state = PropertyDelete, + .atom = prop->propertyName, + .timestamp = currentTime.milliseconds + }; + RRDeliverPropertyEvent(provider->pScreen, (xEvent *) &event); + } + + if (client->swapped) { + swaps(&reply.sequenceNumber, n); + swapl(&reply.length, n); + swapl(&reply.propertyType, n); + swapl(&reply.bytesAfter, n); + swapl(&reply.nItems, n); + } + WriteToClient(client, sizeof(xGenericReply), (char *) &reply); + if (len) { + memcpy(extra, (char *) prop_value->data + ind, len); + switch (reply.format) { + case 32: + client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write; + break; + case 16: + client->pSwapReplyFunc = (ReplySwapPtr) CopySwap16Write; + break; + default: + client->pSwapReplyFunc = (ReplySwapPtr) WriteToClient; + break; + } + WriteSwappedDataToClient(client, len, extra); + xfree(extra); + } + + if (stuff->delete && (reply.bytesAfter == 0)) { /* delete the Property */ + *prev = prop->next; + RRDestroyProviderProperty(prop); + } + return Success; +} diff --git a/nx-X11/programs/Xserver/randr/rrscreen.c b/nx-X11/programs/Xserver/randr/rrscreen.c index 458416c1f..af54d66f5 100644 --- a/nx-X11/programs/Xserver/randr/rrscreen.c +++ b/nx-X11/programs/Xserver/randr/rrscreen.c @@ -39,10 +39,6 @@ #include "randrstr.h" -extern char *ConnectionInfo; - -static int padlength[4] = { 0, 3, 2, 1 }; - static CARD16 RR10CurrentSizeID(ScreenPtr pScreen); @@ -65,8 +61,7 @@ RREditConnectionInfo(ScreenPtr pScreen) connSetup = (xConnSetup *) ConnectionInfo; vendor = (char *) connSetup + sizeof(xConnSetup); formats = (xPixmapFormat *) ((char *) vendor + - connSetup->nbytesVendor + - padlength[connSetup->nbytesVendor & 3]); + pad_to_int32(connSetup->nbytesVendor)); root = (xWindowRoot *) ((char *) formats + sizeof(xPixmapFormat) * screenInfo.numPixmapFormats); @@ -89,21 +84,21 @@ RREditConnectionInfo(ScreenPtr pScreen) void RRSendConfigNotify(ScreenPtr pScreen) { - WindowPtr pWin = WindowTable[pScreen->myNum]; - xEvent event; - + WindowPtr pWin = pScreen->root; + xEvent event = { + .u.configureNotify.window = pWin->drawable.id, + .u.configureNotify.aboveSibling = None, + .u.configureNotify.x = 0, + .u.configureNotify.y = 0, + + /* XXX xinerama stuff ? */ + + .u.configureNotify.width = pWin->drawable.width, + .u.configureNotify.height = pWin->drawable.height, + .u.configureNotify.borderWidth = wBorderWidth(pWin), + .u.configureNotify.override = pWin->overrideRedirect + }; event.u.u.type = ConfigureNotify; - event.u.configureNotify.window = pWin->drawable.id; - event.u.configureNotify.aboveSibling = None; - event.u.configureNotify.x = 0; - event.u.configureNotify.y = 0; - - /* XXX xinerama stuff ? */ - - event.u.configureNotify.width = pWin->drawable.width; - event.u.configureNotify.height = pWin->drawable.height; - event.u.configureNotify.borderWidth = wBorderWidth(pWin); - event.u.configureNotify.override = pWin->overrideRedirect; DeliverEvents(pWin, &event, 1, NullWindow); } @@ -111,25 +106,23 @@ void RRDeliverScreenEvent(ClientPtr client, WindowPtr pWin, ScreenPtr pScreen) { rrScrPriv(pScreen); - xRRScreenChangeNotifyEvent se; RRCrtcPtr crtc = pScrPriv->numCrtcs ? pScrPriv->crtcs[0] : NULL; - WindowPtr pRoot = WindowTable[pScreen->myNum]; - - se.type = RRScreenChangeNotify + RREventBase; - se.rotation = (CARD8) (crtc ? crtc->rotation : RR_Rotate_0); - se.timestamp = pScrPriv->lastSetTime.milliseconds; - se.sequenceNumber = client->sequence; - se.configTimestamp = pScrPriv->lastConfigTime.milliseconds; - se.root = pRoot->drawable.id; - se.window = pWin->drawable.id; -#ifdef RENDER - se.subpixelOrder = PictureGetSubpixelOrder(pScreen); -#else - se.subpixelOrder = SubPixelUnknown; + WindowPtr pRoot = pScreen->root; + + xRRScreenChangeNotifyEvent se = { + .type = RRScreenChangeNotify + RREventBase, +#ifdef NXAGENT_SERVER + .sequenceNumber = client->sequence, #endif + .rotation = (CARD8) (crtc ? crtc->rotation : RR_Rotate_0), + .timestamp = pScrPriv->lastSetTime.milliseconds, + .configTimestamp = pScrPriv->lastConfigTime.milliseconds, + .root = pRoot->drawable.id, + .window = pWin->drawable.id, + .subpixelOrder = PictureGetSubpixelOrder(pScreen), - se.sequenceNumber = client->sequence; - se.sizeID = RR10CurrentSizeID(pScreen); + .sizeID = RR10CurrentSizeID(pScreen) + }; if (se.rotation & (RR_Rotate_90 | RR_Rotate_270)) { se.widthInPixels = pScreen->height; @@ -144,7 +137,7 @@ RRDeliverScreenEvent(ClientPtr client, WindowPtr pWin, ScreenPtr pScreen) se.heightInMillimeters = pScreen->mmHeight; } - WriteEventsToClient(client, 1, (xEvent *) &se); + WriteEventsToClient(client, 1, (xEvent *) (char *) &se); } /* @@ -170,7 +163,7 @@ RRScreenSizeNotify(ScreenPtr pScreen) pScrPriv->height = pScreen->height; pScrPriv->mmWidth = pScreen->mmWidth; pScrPriv->mmHeight = pScreen->mmHeight; - pScrPriv->changed = TRUE; + RRSetChanged(pScreen); /* pScrPriv->sizeChanged = TRUE; */ RRTellChanged(pScreen); @@ -219,27 +212,31 @@ ProcRRGetScreenSizeRange(ClientPtr client) ScreenPtr pScreen; rrScrPrivPtr pScrPriv; int rc; + int n; REQUEST_SIZE_MATCH(xRRGetScreenSizeRangeReq); #ifndef NXAGENT_SERVER - rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); #else pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess); rc = pWin ? Success : BadWindow; #endif + if (rc != Success) return rc; pScreen = pWin->drawable.pScreen; pScrPriv = rrGetScrPriv(pScreen); - rep.type = X_Reply; - rep.pad = 0; - rep.sequenceNumber = client->sequence; - rep.length = 0; + rep = (xRRGetScreenSizeRangeReply) { + .type = X_Reply, + .pad = 0, + .sequenceNumber = client->sequence, + .length = 0 + }; if (pScrPriv) { - if (!RRGetInfo(pScreen)) + if (!RRGetInfo(pScreen, FALSE)) return BadAlloc; rep.minWidth = pScrPriv->minWidth; rep.minHeight = pScrPriv->minHeight; @@ -251,8 +248,6 @@ ProcRRGetScreenSizeRange(ClientPtr client) rep.maxHeight = rep.minHeight = pScreen->height; } if (client->swapped) { - int n; - swaps(&rep.sequenceNumber, n); swapl(&rep.length, n); swaps(&rep.minWidth, n); @@ -261,7 +256,7 @@ ProcRRGetScreenSizeRange(ClientPtr client) swaps(&rep.maxHeight, n); } WriteToClient(client, sizeof(xRRGetScreenSizeRangeReply), (char *) &rep); - return (client->noClientException); + return Success; } int @@ -275,7 +270,7 @@ ProcRRSetScreenSize(ClientPtr client) REQUEST_SIZE_MATCH(xRRSetScreenSizeReq); #ifndef NXAGENT_SERVER - rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); #else pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess); rc = pWin ? Success : BadWindow; @@ -285,6 +280,9 @@ ProcRRSetScreenSize(ClientPtr client) pScreen = pWin->drawable.pScreen; pScrPriv = rrGetScrPriv(pScreen); + if (!pScrPriv) + return BadMatch; + if (stuff->width < pScrPriv->minWidth || pScrPriv->maxWidth < stuff->width) { client->errorValue = stuff->width; return BadValue; @@ -326,8 +324,194 @@ ProcRRSetScreenSize(ClientPtr client) return Success; } -int -ProcRRGetScreenResources(ClientPtr client) + +#define update_totals(gpuscreen, pScrPriv) do { \ + total_crtcs += pScrPriv->numCrtcs; \ + total_outputs += pScrPriv->numOutputs; \ + modes = RRModesForScreen(gpuscreen, &num_modes); \ + if (!modes) \ + return BadAlloc; \ + for (j = 0; j < num_modes; j++) \ + total_name_len += modes[j]->mode.nameLength; \ + total_modes += num_modes; \ + xfree(modes); \ +} while(0) + +static inline void +swap_modeinfos(xRRModeInfo * modeinfos, int i) +{ + int n; + + swapl(&modeinfos[i].id, n); + swaps(&modeinfos[i].width, n); + swaps(&modeinfos[i].height, n); + swapl(&modeinfos[i].dotClock, n); + swaps(&modeinfos[i].hSyncStart, n); + swaps(&modeinfos[i].hSyncEnd, n); + swaps(&modeinfos[i].hTotal, n); + swaps(&modeinfos[i].hSkew, n); + swaps(&modeinfos[i].vSyncStart, n); + swaps(&modeinfos[i].vSyncEnd, n); + swaps(&modeinfos[i].vTotal, n); + swaps(&modeinfos[i].nameLength, n); + swapl(&modeinfos[i].modeFlags, n); +} + +#define update_arrays(gpuscreen, pScrPriv, primary_crtc, has_primary) do { \ + for (j = 0; j < pScrPriv->numCrtcs; j++) { \ + if (has_primary && \ + primary_crtc == pScrPriv->crtcs[j]) { \ + has_primary = 0; \ + continue; \ + }\ + crtcs[crtc_count] = pScrPriv->crtcs[j]->id; \ + if (client->swapped) \ + swapl(&crtcs[crtc_count], n); \ + crtc_count++; \ + } \ + for (j = 0; j < pScrPriv->numOutputs; j++) { \ + outputs[output_count] = pScrPriv->outputs[j]->id; \ + if (client->swapped) \ + swapl(&outputs[output_count], n); \ + output_count++; \ + } \ + { \ + RRModePtr mode; \ + modes = RRModesForScreen(gpuscreen, &num_modes); \ + for (j = 0; j < num_modes; j++) { \ + mode = modes[j]; \ + modeinfos[mode_count] = mode->mode; \ + if (client->swapped) { \ + swap_modeinfos(modeinfos, mode_count); \ + } \ + memcpy(names, mode->name, mode->mode.nameLength); \ + names += mode->mode.nameLength; \ + mode_count++; \ + } \ + xfree(modes); \ + } \ + } while (0) + +#ifndef NXAGENT_SERVER +static int +rrGetMultiScreenResources(ClientPtr client, Bool query, ScreenPtr pScreen) +{ + int j; + int total_crtcs, total_outputs, total_modes, total_name_len; + int crtc_count, output_count, mode_count; + ScreenPtr iter; + rrScrPrivPtr pScrPriv; + int num_modes; + RRModePtr *modes; + xRRGetScreenResourcesReply rep; + unsigned long extraLen; + CARD8 *extra; + RRCrtc *crtcs; + RRCrtcPtr primary_crtc = NULL; + RROutput *outputs; + xRRModeInfo *modeinfos; + CARD8 *names; + int has_primary = 0; + int n; + + /* we need to iterate all the GPU masters and all their output slaves */ + total_crtcs = 0; + total_outputs = 0; + total_modes = 0; + total_name_len = 0; + + pScrPriv = rrGetScrPriv(pScreen); + + if (query && pScrPriv) + if (!RRGetInfo(pScreen, query)) + return BadAlloc; + + update_totals(pScreen, pScrPriv); + + xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) { + pScrPriv = rrGetScrPriv(iter); + + if (query) + if (!RRGetInfo(iter, query)) + return BadAlloc; + update_totals(iter, pScrPriv); + } + + pScrPriv = rrGetScrPriv(pScreen); + rep = (xRRGetScreenResourcesReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0, + .timestamp = pScrPriv->lastSetTime.milliseconds, + .configTimestamp = pScrPriv->lastConfigTime.milliseconds, + .nCrtcs = total_crtcs, + .nOutputs = total_outputs, + .nModes = total_modes, + .nbytesNames = total_name_len + }; + + rep.length = (total_crtcs + total_outputs + + total_modes * bytes_to_int32(SIZEOF(xRRModeInfo)) + + bytes_to_int32(total_name_len)); + + extraLen = rep.length << 2; + if (extraLen) { + extra = xalloc(extraLen); + if (!extra) { + return BadAlloc; + } + } + else + extra = NULL; + + crtcs = (RRCrtc *) extra; + outputs = (RROutput *) (crtcs + total_crtcs); + modeinfos = (xRRModeInfo *) (outputs + total_outputs); + names = (CARD8 *) (modeinfos + total_modes); + + crtc_count = 0; + output_count = 0; + mode_count = 0; + + pScrPriv = rrGetScrPriv(pScreen); + if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc) { + has_primary = 1; + primary_crtc = pScrPriv->primaryOutput->crtc; + crtcs[0] = pScrPriv->primaryOutput->crtc->id; + if (client->swapped) + swapl(&crtcs[0], n); + crtc_count = 1; + } + update_arrays(pScreen, pScrPriv, primary_crtc, has_primary); + + xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) { + pScrPriv = rrGetScrPriv(iter); + + update_arrays(iter, pScrPriv, primary_crtc, has_primary); + } + + assert(bytes_to_int32((char *) names - (char *) extra) == rep.length); + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.timestamp, n); + swapl(&rep.configTimestamp, n); + swaps(&rep.nCrtcs, n); + swaps(&rep.nOutputs, n); + swaps(&rep.nModes, n); + swaps(&rep.nbytesNames, n); + } + WriteToClient(client, sizeof(xRRGetScreenResourcesReply), (char *) &rep); + if (extraLen) { + WriteToClient(client, extraLen, (char *) extra); + xfree(extra); + } + return Success; +} +#endif /* !defined(NXAGENT_SERVER) */ + +static int +rrGetScreenResources(ClientPtr client, Bool query) { REQUEST(xRRGetScreenResourcesReq); xRRGetScreenResourcesReply rep; @@ -336,15 +520,17 @@ ProcRRGetScreenResources(ClientPtr client) rrScrPrivPtr pScrPriv; CARD8 *extra; unsigned long extraLen; - int i, n, rc; + int i, rc, has_primary = 0; RRCrtc *crtcs; RROutput *outputs; xRRModeInfo *modeinfos; CARD8 *names; + int n; REQUEST_SIZE_MATCH(xRRGetScreenResourcesReq); + #ifndef NXAGENT_SERVER - rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); #else pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess); rc = pWin ? Success : BadWindow; @@ -354,22 +540,28 @@ ProcRRGetScreenResources(ClientPtr client) pScreen = pWin->drawable.pScreen; pScrPriv = rrGetScrPriv(pScreen); - rep.pad = 0; - if (pScrPriv) - if (!RRGetInfo(pScreen)) + if (query && pScrPriv) + if (!RRGetInfo(pScreen, query)) return BadAlloc; +#ifndef NXAGENT_SERVER + if (!xorg_list_is_empty(&pScreen->output_slave_list)) + return rrGetMultiScreenResources(client, query, pScreen); +#endif + if (!pScrPriv) { - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.timestamp = currentTime.milliseconds; - rep.configTimestamp = currentTime.milliseconds; - rep.nCrtcs = 0; - rep.nOutputs = 0; - rep.nModes = 0; - rep.nbytesNames = 0; + rep = (xRRGetScreenResourcesReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0, + .timestamp = currentTime.milliseconds, + .configTimestamp = currentTime.milliseconds, + .nCrtcs = 0, + .nOutputs = 0, + .nModes = 0, + .nbytesNames = 0 + }; extra = NULL; extraLen = 0; } @@ -381,23 +573,25 @@ ProcRRGetScreenResources(ClientPtr client) if (!modes) return BadAlloc; - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.timestamp = pScrPriv->lastSetTime.milliseconds; - rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds; - rep.nCrtcs = pScrPriv->numCrtcs; - rep.nOutputs = pScrPriv->numOutputs; - rep.nModes = num_modes; - rep.nbytesNames = 0; + rep = (xRRGetScreenResourcesReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0, + .timestamp = pScrPriv->lastSetTime.milliseconds, + .configTimestamp = pScrPriv->lastConfigTime.milliseconds, + .nCrtcs = pScrPriv->numCrtcs, + .nOutputs = pScrPriv->numOutputs, + .nModes = num_modes, + .nbytesNames = 0 + }; for (i = 0; i < num_modes; i++) rep.nbytesNames += modes[i]->mode.nameLength; rep.length = (pScrPriv->numCrtcs + pScrPriv->numOutputs + - num_modes * (SIZEOF(xRRModeInfo) >> 2) + - ((rep.nbytesNames + 3) >> 2)); + num_modes * bytes_to_int32(SIZEOF(xRRModeInfo)) + + bytes_to_int32(rep.nbytesNames)); extraLen = rep.length << 2; if (extraLen) { @@ -415,10 +609,22 @@ ProcRRGetScreenResources(ClientPtr client) modeinfos = (xRRModeInfo *) (outputs + pScrPriv->numOutputs); names = (CARD8 *) (modeinfos + num_modes); + if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc) { + has_primary = 1; + crtcs[0] = pScrPriv->primaryOutput->crtc->id; + if (client->swapped) + swapl(&crtcs[0], n); + } + for (i = 0; i < pScrPriv->numCrtcs; i++) { - crtcs[i] = pScrPriv->crtcs[i]->id; + if (has_primary && + pScrPriv->primaryOutput->crtc == pScrPriv->crtcs[i]) { + has_primary = 0; + continue; + } + crtcs[i + has_primary] = pScrPriv->crtcs[i]->id; if (client->swapped) - swapl(&crtcs[i], n); + swapl(&crtcs[i + has_primary], n); } for (i = 0; i < pScrPriv->numOutputs; i++) { @@ -450,7 +656,7 @@ ProcRRGetScreenResources(ClientPtr client) names += mode->mode.nameLength; } xfree(modes); - assert(((((char *) names - (char *) extra) + 3) >> 2) == rep.length); + assert(bytes_to_int32((char *) names - (char *) extra) == rep.length); } if (client->swapped) { @@ -463,12 +669,25 @@ ProcRRGetScreenResources(ClientPtr client) swaps(&rep.nModes, n); swaps(&rep.nbytesNames, n); } - WriteToClient(client, sizeof(xRRGetScreenResourcesReply), (char *) &rep); + WriteToClient(client, sizeof(xRRGetScreenResourcesReply), + (char *) (char *) &rep); if (extraLen) { - WriteToClient(client, extraLen, (char *) extra); + WriteToClient(client, extraLen, (char *) (char *) extra); xfree(extra); } - return client->noClientException; + return Success; +} + +int +ProcRRGetScreenResources(ClientPtr client) +{ + return rrGetScreenResources(client, TRUE); +} + +int +ProcRRGetScreenResourcesCurrent(ClientPtr client) +{ + return rrGetScreenResources(client, FALSE); } typedef struct _RR10Data { @@ -495,7 +714,7 @@ RR10GetData(ScreenPtr pScreen, RROutputPtr output) Bool *used; /* Make sure there is plenty of space for any combination */ - data = malloc(sizeof(RR10DataRec) + + data = xalloc(sizeof(RR10DataRec) + sizeof(RRScreenSize) * nmode + sizeof(RRScreenRate) * nmode + sizeof(Bool) * nmode); if (!data) @@ -576,46 +795,49 @@ ProcRRGetScreenInfo(ClientPtr client) REQUEST(xRRGetScreenInfoReq); xRRGetScreenInfoReply rep; WindowPtr pWin; - int n, rc; + int rc; ScreenPtr pScreen; rrScrPrivPtr pScrPriv; CARD8 *extra; unsigned long extraLen; RROutputPtr output; + int n; REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); #ifndef NXAGENT_SERVER - rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); #else pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess); rc = pWin ? Success : BadWindow; #endif + if (rc != Success) return rc; pScreen = pWin->drawable.pScreen; pScrPriv = rrGetScrPriv(pScreen); - rep.pad = 0; if (pScrPriv) - if (!RRGetInfo(pScreen)) + if (!RRGetInfo(pScreen, TRUE)) return BadAlloc; output = RRFirstOutput(pScreen); if (!pScrPriv || !output) { - rep.type = X_Reply; - rep.setOfRotations = RR_Rotate_0;; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id; - rep.timestamp = currentTime.milliseconds; - rep.configTimestamp = currentTime.milliseconds; - rep.nSizes = 0; - rep.sizeID = 0; - rep.rotation = RR_Rotate_0; - rep.rate = 0; - rep.nrateEnts = 0; + rep = (xRRGetScreenInfoReply) { + .type = X_Reply, + .setOfRotations = RR_Rotate_0, + .sequenceNumber = client->sequence, + .length = 0, + .root = pWin->drawable.pScreen->root->drawable.id, + .timestamp = currentTime.milliseconds, + .configTimestamp = currentTime.milliseconds, + .nSizes = 0, + .sizeID = 0, + .rotation = RR_Rotate_0, + .rate = 0, + .nrateEnts = 0 + }; extra = 0; extraLen = 0; } @@ -632,18 +854,20 @@ ProcRRGetScreenInfo(ClientPtr client) if (!pData) return BadAlloc; - rep.type = X_Reply; - rep.setOfRotations = output->crtc->rotations; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id; - rep.timestamp = pScrPriv->lastSetTime.milliseconds; - rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds; - rep.rotation = output->crtc->rotation; - rep.nSizes = pData->nsize; - rep.nrateEnts = pData->nrefresh + pData->nsize; - rep.sizeID = pData->size; - rep.rate = pData->refresh; + rep = (xRRGetScreenInfoReply) { + .type = X_Reply, + .setOfRotations = output->crtc->rotations, + .sequenceNumber = client->sequence, + .length = 0, + .root = pWin->drawable.pScreen->root->drawable.id, + .timestamp = pScrPriv->lastSetTime.milliseconds, + .configTimestamp = pScrPriv->lastConfigTime.milliseconds, + .rotation = output->crtc->rotation, + .nSizes = pData->nsize, + .nrateEnts = pData->nrefresh + pData->nsize, + .sizeID = pData->size, + .rate = pData->refresh + }; extraLen = rep.nSizes * sizeof(xScreenSizes); if (has_rate) @@ -699,7 +923,7 @@ ProcRRGetScreenInfo(ClientPtr client) if (data8 - (CARD8 *) extra != extraLen) FatalError("RRGetScreenInfo bad extra len %ld != %ld\n", (unsigned long) (data8 - (CARD8 *) extra), extraLen); - rep.length = (extraLen + 3) >> 2; + rep.length = bytes_to_int32(extraLen); } if (client->swapped) { swaps(&rep.sequenceNumber, n); @@ -717,7 +941,7 @@ ProcRRGetScreenInfo(ClientPtr client) WriteToClient(client, extraLen, (char *) extra); xfree(extra); } - return (client->noClientException); + return Success; } int @@ -726,7 +950,7 @@ ProcRRSetScreenConfig(ClientPtr client) REQUEST(xRRSetScreenConfigReq); xRRSetScreenConfigReply rep; DrawablePtr pDraw; - int n, rc; + int rc; ScreenPtr pScreen; rrScrPrivPtr pScrPriv; TimeStamp time; @@ -734,12 +958,14 @@ ProcRRSetScreenConfig(ClientPtr client) Rotation rotation; int rate; Bool has_rate; + CARD8 status; RROutputPtr output; RRCrtcPtr crtc; RRModePtr mode; RR10DataPtr pData = NULL; RRScreenSizePtr pSize; int width, height; + int n; UpdateCurrentTime(); @@ -754,11 +980,12 @@ ProcRRSetScreenConfig(ClientPtr client) #ifndef NXAGENT_SERVER rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess); -#else +#else /* !defined(NXAGENT_SERVER) */ pDraw = SecurityLookupDrawable(stuff->drawable, client, SecurityWriteAccess); rc = pDraw ? Success : BadDrawable; -#endif +#endif /* !defined(NXAGENT_SERVER) */ + if (rc != Success) return rc; @@ -770,16 +997,16 @@ ProcRRSetScreenConfig(ClientPtr client) if (!pScrPriv) { time = currentTime; - rep.status = RRSetConfigFailed; + status = RRSetConfigFailed; goto sendReply; } - if (!RRGetInfo(pScreen)) + if (!RRGetInfo(pScreen, FALSE)) return BadAlloc; output = RRFirstOutput(pScreen); if (!output) { time = currentTime; - rep.status = RRSetConfigFailed; + status = RRSetConfigFailed; goto sendReply; } @@ -795,7 +1022,7 @@ ProcRRSetScreenConfig(ClientPtr client) * stop working after several hours have passed (freedesktop bug #6502). */ if (stuff->configTimestamp != pScrPriv->lastConfigTime.milliseconds) { - rep.status = RRSetConfigInvalidConfigTime; + status = RRSetConfigInvalidConfigTime; goto sendReply; } @@ -874,7 +1101,7 @@ ProcRRSetScreenConfig(ClientPtr client) * the last set-time */ if (CompareTimeStamps(time, pScrPriv->lastSetTime) < 0) { - rep.status = RRSetConfigInvalidTime; + status = RRSetConfigInvalidTime; goto sendReply; } @@ -884,11 +1111,6 @@ ProcRRSetScreenConfig(ClientPtr client) */ width = mode->mode.width; height = mode->mode.height; - if (rotation & (RR_Rotate_90 | RR_Rotate_270)) { - width = mode->mode.height; - height = mode->mode.width; - } - if (width < pScrPriv->minWidth || pScrPriv->maxWidth < width) { client->errorValue = width; xfree(pData); @@ -900,30 +1122,35 @@ ProcRRSetScreenConfig(ClientPtr client) return BadValue; } + if (rotation & (RR_Rotate_90 | RR_Rotate_270)) { + width = mode->mode.height; + height = mode->mode.width; + } + if (width != pScreen->width || height != pScreen->height) { int c; for (c = 0; c < pScrPriv->numCrtcs; c++) { if (!RRCrtcSet(pScrPriv->crtcs[c], NULL, 0, 0, RR_Rotate_0, 0, NULL)) { - rep.status = RRSetConfigFailed; + status = RRSetConfigFailed; /* XXX recover from failure */ goto sendReply; } } if (!RRScreenSizeSet(pScreen, width, height, pScreen->mmWidth, pScreen->mmHeight)) { - rep.status = RRSetConfigFailed; + status = RRSetConfigFailed; /* XXX recover from failure */ goto sendReply; } } if (!RRCrtcSet(crtc, mode, 0, 0, stuff->rotation, 1, &output)) - rep.status = RRSetConfigFailed; + status = RRSetConfigFailed; else { pScrPriv->lastSetTime = time; - rep.status = RRSetConfigSuccess; + status = RRSetConfigSuccess; } /* @@ -932,17 +1159,18 @@ ProcRRSetScreenConfig(ClientPtr client) sendReply: - if (pData) - xfree(pData); - - rep.type = X_Reply; - /* rep.status has already been filled in */ - rep.length = 0; - rep.sequenceNumber = client->sequence; + xfree(pData); - rep.newTimestamp = pScrPriv->lastSetTime.milliseconds; - rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds; - rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id; + rep = (xRRSetScreenConfigReply) { + .type = X_Reply, + .status = status, + .sequenceNumber = client->sequence, + .length = 0, + .newTimestamp = pScrPriv->lastSetTime.milliseconds, + .newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds, + .root = pDraw->pScreen->root->drawable.id, + /* .subpixelOrder = ?? */ + }; if (client->swapped) { swaps(&rep.sequenceNumber, n); @@ -953,7 +1181,7 @@ ProcRRSetScreenConfig(ClientPtr client) } WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *) &rep); - return (client->noClientException); + return Success; } static CARD16 diff --git a/nx-X11/programs/Xserver/randr/rrsdispatch.c b/nx-X11/programs/Xserver/randr/rrsdispatch.c index 3175340fa..6ac394344 100644 --- a/nx-X11/programs/Xserver/randr/rrsdispatch.c +++ b/nx-X11/programs/Xserver/randr/rrsdispatch.c @@ -25,7 +25,7 @@ static int SProcRRQueryVersion(ClientPtr client) { - register int n; + int n; REQUEST(xRRQueryVersionReq); @@ -39,7 +39,7 @@ SProcRRQueryVersion(ClientPtr client) static int SProcRRGetScreenInfo(ClientPtr client) { - register int n; + int n; REQUEST(xRRGetScreenInfoReq); @@ -52,7 +52,7 @@ SProcRRGetScreenInfo(ClientPtr client) static int SProcRRSetScreenConfig(ClientPtr client) { - register int n; + int n; REQUEST(xRRSetScreenConfigReq); @@ -75,7 +75,7 @@ SProcRRSetScreenConfig(ClientPtr client) static int SProcRRSelectInput(ClientPtr client) { - register int n; + int n; REQUEST(xRRSelectInputReq); @@ -134,7 +134,7 @@ SProcRRGetOutputInfo(ClientPtr client) { int n; - REQUEST(xRRGetOutputInfoReq);; + REQUEST(xRRGetOutputInfoReq); REQUEST_SIZE_MATCH(xRRGetOutputInfoReq); swaps(&stuff->length, n); @@ -177,6 +177,7 @@ SProcRRConfigureOutputProperty(ClientPtr client) REQUEST(xRRConfigureOutputPropertyReq); + REQUEST_AT_LEAST_SIZE(xRRConfigureOutputPropertyReq); swaps(&stuff->length, n); swapl(&stuff->output, n); swapl(&stuff->property, n); @@ -248,6 +249,7 @@ static int SProcRRCreateMode(ClientPtr client) { int n; + xRRModeInfo *modeinfo; REQUEST(xRRCreateModeReq); @@ -388,6 +390,315 @@ SProcRRSetCrtcGamma(ClientPtr client) return (*ProcRandrVector[stuff->randrReqType]) (client); } +static int +SProcRRSetCrtcTransform(ClientPtr client) +{ + int nparams; + char *filter; + CARD32 *params; + int n; + + REQUEST(xRRSetCrtcTransformReq); + + REQUEST_AT_LEAST_SIZE(xRRSetCrtcTransformReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + SwapLongs((CARD32 *) &stuff->transform, + bytes_to_int32(sizeof(xRenderTransform))); + swaps(&stuff->nbytesFilter, n); + filter = (char *) (stuff + 1); + params = (CARD32 *) (filter + pad_to_int32(stuff->nbytesFilter)); + nparams = ((CARD32 *) stuff + client->req_len) - params; + if (nparams < 0) + return BadLength; + + SwapLongs(params, nparams); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetCrtcTransform(ClientPtr client) +{ + int n; + + REQUEST(xRRGetCrtcTransformReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcTransformReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetPanning(ClientPtr client) +{ + int n; + + REQUEST(xRRGetPanningReq); + + REQUEST_SIZE_MATCH(xRRGetPanningReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRSetPanning(ClientPtr client) +{ + int n; + + REQUEST(xRRSetPanningReq); + + REQUEST_SIZE_MATCH(xRRSetPanningReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + swapl(&stuff->timestamp, n); + swaps(&stuff->left, n); + swaps(&stuff->top, n); + swaps(&stuff->width, n); + swaps(&stuff->height, n); + swaps(&stuff->track_left, n); + swaps(&stuff->track_top, n); + swaps(&stuff->track_width, n); + swaps(&stuff->track_height, n); + swaps(&stuff->border_left, n); + swaps(&stuff->border_top, n); + swaps(&stuff->border_right, n); + swaps(&stuff->border_bottom, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRSetOutputPrimary(ClientPtr client) +{ + int n; + + REQUEST(xRRSetOutputPrimaryReq); + + REQUEST_SIZE_MATCH(xRRSetOutputPrimaryReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + swapl(&stuff->output, n); + return ProcRandrVector[stuff->randrReqType] (client); +} + +static int +SProcRRGetOutputPrimary(ClientPtr client) +{ + int n; + + REQUEST(xRRGetOutputPrimaryReq); + + REQUEST_SIZE_MATCH(xRRGetOutputPrimaryReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + return ProcRandrVector[stuff->randrReqType] (client); +} + +static int +SProcRRGetProviders(ClientPtr client) +{ + int n; + + REQUEST(xRRGetProvidersReq); + + REQUEST_SIZE_MATCH(xRRGetProvidersReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + return ProcRandrVector[stuff->randrReqType] (client); +} + +static int +SProcRRGetProviderInfo(ClientPtr client) +{ + int n; + + REQUEST(xRRGetProviderInfoReq); + + REQUEST_SIZE_MATCH(xRRGetProviderInfoReq); + swaps(&stuff->length, n); + swapl(&stuff->provider, n); + swapl(&stuff->configTimestamp, n); + return ProcRandrVector[stuff->randrReqType] (client); +} + +static int +SProcRRSetProviderOffloadSink(ClientPtr client) +{ + int n; + + REQUEST(xRRSetProviderOffloadSinkReq); + + REQUEST_SIZE_MATCH(xRRSetProviderOffloadSinkReq); + swaps(&stuff->length, n); + swapl(&stuff->provider, n); + swapl(&stuff->sink_provider, n); + swapl(&stuff->configTimestamp, n); + return ProcRandrVector[stuff->randrReqType] (client); +} + +static int +SProcRRSetProviderOutputSource(ClientPtr client) +{ + int n; + + REQUEST(xRRSetProviderOutputSourceReq); + + REQUEST_SIZE_MATCH(xRRSetProviderOutputSourceReq); + swaps(&stuff->length, n); + swapl(&stuff->provider, n); + swapl(&stuff->source_provider, n); + swapl(&stuff->configTimestamp, n); + return ProcRandrVector[stuff->randrReqType] (client); +} + +static int +SProcRRListProviderProperties(ClientPtr client) +{ + int n; + + REQUEST(xRRListProviderPropertiesReq); + + REQUEST_SIZE_MATCH(xRRListProviderPropertiesReq); + swaps(&stuff->length, n); + swapl(&stuff->provider, n); + return ProcRandrVector[stuff->randrReqType] (client); +} + +static int +SProcRRQueryProviderProperty(ClientPtr client) +{ + int n; + + REQUEST(xRRQueryProviderPropertyReq); + + REQUEST_SIZE_MATCH(xRRQueryProviderPropertyReq); + swaps(&stuff->length, n); + swapl(&stuff->provider, n); + swapl(&stuff->property, n); + return ProcRandrVector[stuff->randrReqType] (client); +} + +static int +SProcRRConfigureProviderProperty(ClientPtr client) +{ + int n; + + REQUEST(xRRConfigureProviderPropertyReq); + + REQUEST_AT_LEAST_SIZE(xRRConfigureProviderPropertyReq); + swaps(&stuff->length, n); + swapl(&stuff->provider, n); + swapl(&stuff->property, n); + /* TODO: no way to specify format? */ + SwapRestL(stuff); + return ProcRandrVector[stuff->randrReqType] (client); +} + +static int +SProcRRChangeProviderProperty(ClientPtr client) +{ + int n; + + REQUEST(xRRChangeProviderPropertyReq); + + REQUEST_AT_LEAST_SIZE(xRRChangeProviderPropertyReq); + swaps(&stuff->length, n); + swapl(&stuff->provider, n); + swapl(&stuff->property, n); + swapl(&stuff->type, n); + swapl(&stuff->nUnits, n); + switch (stuff->format) { + case 8: + break; + case 16: + SwapRestS(stuff); + break; + case 32: + SwapRestL(stuff); + break; + } + return ProcRandrVector[stuff->randrReqType] (client); +} + +static int +SProcRRDeleteProviderProperty(ClientPtr client) +{ + int n; + + REQUEST(xRRDeleteProviderPropertyReq); + + REQUEST_SIZE_MATCH(xRRDeleteProviderPropertyReq); + swaps(&stuff->length, n); + swapl(&stuff->provider, n); + swapl(&stuff->property, n); + return ProcRandrVector[stuff->randrReqType] (client); +} + +static int +SProcRRGetProviderProperty(ClientPtr client) +{ + int n; + + REQUEST(xRRGetProviderPropertyReq); + + REQUEST_SIZE_MATCH(xRRGetProviderPropertyReq); + swaps(&stuff->length, n); + swapl(&stuff->provider, n); + swapl(&stuff->property, n); + swapl(&stuff->type, n); + swapl(&stuff->longOffset, n); + swapl(&stuff->longLength, n); + return ProcRandrVector[stuff->randrReqType] (client); +} + +static int +SProcRRGetMonitors(ClientPtr client) +{ + int n; + + REQUEST(xRRGetMonitorsReq); + + REQUEST_SIZE_MATCH(xRRGetMonitorsReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + return ProcRandrVector[stuff->randrReqType] (client); +} + +static int +SProcRRSetMonitor(ClientPtr client) +{ + int n; + + REQUEST(xRRSetMonitorReq); + + REQUEST_AT_LEAST_SIZE(xRRGetMonitorsReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + swapl(&stuff->monitor.name, n); + swaps(&stuff->monitor.noutput, n); + swaps(&stuff->monitor.x, n); + swaps(&stuff->monitor.y, n); + swaps(&stuff->monitor.width, n); + swaps(&stuff->monitor.height, n); + SwapRestL(stuff); + return ProcRandrVector[stuff->randrReqType] (client); +} + +static int +SProcRRDeleteMonitor(ClientPtr client) +{ + int n; + + REQUEST(xRRDeleteMonitorReq); + + REQUEST_SIZE_MATCH(xRRDeleteMonitorReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + swapl(&stuff->name, n); + return ProcRandrVector[stuff->randrReqType] (client); +} + int (*SProcRandrVector[RRNumberRequests]) (ClientPtr) = { SProcRRQueryVersion, /* 0 */ /* we skip 1 to make old clients fail pretty immediately */ @@ -418,4 +729,26 @@ int (*SProcRandrVector[RRNumberRequests]) (ClientPtr) = { SProcRRGetCrtcGammaSize, /* 22 */ SProcRRGetCrtcGamma, /* 23 */ SProcRRSetCrtcGamma, /* 24 */ +/* V1.3 additions */ + SProcRRGetScreenResources, /* 25 GetScreenResourcesCurrent */ + SProcRRSetCrtcTransform, /* 26 */ + SProcRRGetCrtcTransform, /* 27 */ + SProcRRGetPanning, /* 28 */ + SProcRRSetPanning, /* 29 */ + SProcRRSetOutputPrimary, /* 30 */ + SProcRRGetOutputPrimary, /* 31 */ +/* V1.4 additions */ + SProcRRGetProviders, /* 32 */ + SProcRRGetProviderInfo, /* 33 */ + SProcRRSetProviderOffloadSink, /* 34 */ + SProcRRSetProviderOutputSource, /* 35 */ + SProcRRListProviderProperties, /* 36 */ + SProcRRQueryProviderProperty, /* 37 */ + SProcRRConfigureProviderProperty, /* 38 */ + SProcRRChangeProviderProperty, /* 39 */ + SProcRRDeleteProviderProperty, /* 40 */ + SProcRRGetProviderProperty, /* 41 */ + SProcRRGetMonitors, /* 42 */ + SProcRRSetMonitor, /* 43 */ + SProcRRDeleteMonitor, /* 44 */ }; diff --git a/nx-X11/programs/Xserver/randr/rrtransform.c b/nx-X11/programs/Xserver/randr/rrtransform.c new file mode 100644 index 000000000..4377d09aa --- /dev/null +++ b/nx-X11/programs/Xserver/randr/rrtransform.c @@ -0,0 +1,301 @@ +/* + * Copyright © 2007 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "randrstr.h" +#include "rrtransform.h" + +void +RRTransformInit(RRTransformPtr transform) +{ + pixman_transform_init_identity(&transform->transform); + pixman_f_transform_init_identity(&transform->f_transform); + pixman_f_transform_init_identity(&transform->f_inverse); + transform->filter = NULL; + transform->params = NULL; + transform->nparams = 0; +} + +void +RRTransformFini(RRTransformPtr transform) +{ + xfree(transform->params); +} + +Bool +RRTransformEqual(RRTransformPtr a, RRTransformPtr b) +{ + if (a && pixman_transform_is_identity(&a->transform)) + a = NULL; + if (b && pixman_transform_is_identity(&b->transform)) + b = NULL; + if (a == NULL && b == NULL) + return TRUE; + if (a == NULL || b == NULL) + return FALSE; + if (memcmp(&a->transform, &b->transform, sizeof(a->transform)) != 0) + return FALSE; + if (a->filter != b->filter) + return FALSE; + if (a->nparams != b->nparams) + return FALSE; + if (memcmp(a->params, b->params, a->nparams * sizeof(xFixed)) != 0) + return FALSE; + return TRUE; +} + +Bool +RRTransformSetFilter(RRTransformPtr dst, + PictFilterPtr filter, + xFixed * params, int nparams, int width, int height) +{ + xFixed *new_params; + + if (nparams) { +#ifndef NXAGENT_SERVER + new_params = xallocarray(nparams, sizeof(xFixed)); +#else /* !defined(NXAGENT_SERVER) */ + new_params = xalloc(nparams * sizeof(xFixed)); +#endif /* !defined(NXAGENT_SERVER) */ + if (!new_params) + return FALSE; + memcpy(new_params, params, nparams * sizeof(xFixed)); + } + else + new_params = NULL; + xfree(dst->params); + dst->filter = filter; + dst->params = new_params; + dst->nparams = nparams; + dst->width = width; + dst->height = height; + return TRUE; +} + +Bool +RRTransformCopy(RRTransformPtr dst, RRTransformPtr src) +{ + if (src && pixman_transform_is_identity(&src->transform)) + src = NULL; + + if (src) { + if (!RRTransformSetFilter(dst, src->filter, + src->params, src->nparams, src->width, + src->height)) + return FALSE; + dst->transform = src->transform; + dst->f_transform = src->f_transform; + dst->f_inverse = src->f_inverse; + } + else { + if (!RRTransformSetFilter(dst, NULL, NULL, 0, 0, 0)) + return FALSE; + pixman_transform_init_identity(&dst->transform); + pixman_f_transform_init_identity(&dst->f_transform); + pixman_f_transform_init_identity(&dst->f_inverse); + } + return TRUE; +} + +#define F(x) IntToxFixed(x) + +static void +RRTransformRescale(struct pixman_f_transform *f_transform, double limit) +{ + double max = 0, v, scale; + int i, j; + + for (j = 0; j < 3; j++) + for (i = 0; i < 3; i++) + if ((v = fabs(f_transform->m[j][i])) > max) + max = v; + scale = limit / max; + for (j = 0; j < 3; j++) + for (i = 0; i < 3; i++) + f_transform->m[j][i] *= scale; +} + +/* + * Compute the complete transformation matrix including + * client-specified transform, rotation/reflection values and the crtc + * offset. + * + * Return TRUE if the resulting transform is not a simple translation. + */ +Bool +RRTransformCompute(int x, + int y, + int width, + int height, + Rotation rotation, + RRTransformPtr rr_transform, + PictTransformPtr transform, + struct pixman_f_transform *f_transform, + struct pixman_f_transform *f_inverse) +{ + PictTransform t_transform, inverse; + struct pixman_f_transform tf_transform, tf_inverse; + Bool overflow = FALSE; + + if (!transform) + transform = &t_transform; + if (!f_transform) + f_transform = &tf_transform; + if (!f_inverse) + f_inverse = &tf_inverse; + + pixman_transform_init_identity(transform); + pixman_transform_init_identity(&inverse); + pixman_f_transform_init_identity(f_transform); + pixman_f_transform_init_identity(f_inverse); + if (rotation != RR_Rotate_0) { + double f_rot_cos, f_rot_sin, f_rot_dx, f_rot_dy; + double f_scale_x, f_scale_y, f_scale_dx, f_scale_dy; + xFixed rot_cos, rot_sin, rot_dx, rot_dy; + xFixed scale_x, scale_y, scale_dx, scale_dy; + + /* rotation */ + switch (rotation & 0xf) { + default: + case RR_Rotate_0: + f_rot_cos = 1; + f_rot_sin = 0; + f_rot_dx = 0; + f_rot_dy = 0; + rot_cos = F(1); + rot_sin = F(0); + rot_dx = F(0); + rot_dy = F(0); + break; + case RR_Rotate_90: + f_rot_cos = 0; + f_rot_sin = 1; + f_rot_dx = height; + f_rot_dy = 0; + rot_cos = F(0); + rot_sin = F(1); + rot_dx = F(height); + rot_dy = F(0); + break; + case RR_Rotate_180: + f_rot_cos = -1; + f_rot_sin = 0; + f_rot_dx = width; + f_rot_dy = height; + rot_cos = F(~0u); + rot_sin = F(0); + rot_dx = F(width); + rot_dy = F(height); + break; + case RR_Rotate_270: + f_rot_cos = 0; + f_rot_sin = -1; + f_rot_dx = 0; + f_rot_dy = width; + rot_cos = F(0); + rot_sin = F(~0u); + rot_dx = F(0); + rot_dy = F(width); + break; + } + + pixman_transform_rotate(transform, &inverse, rot_cos, rot_sin); + pixman_transform_translate(transform, &inverse, rot_dx, rot_dy); + pixman_f_transform_rotate(f_transform, f_inverse, f_rot_cos, f_rot_sin); + pixman_f_transform_translate(f_transform, f_inverse, f_rot_dx, + f_rot_dy); + + /* reflection */ + f_scale_x = 1; + f_scale_dx = 0; + f_scale_y = 1; + f_scale_dy = 0; + scale_x = F(1); + scale_dx = 0; + scale_y = F(1); + scale_dy = 0; + if (rotation & RR_Reflect_X) { + f_scale_x = -1; + scale_x = F(~0u); + if (rotation & (RR_Rotate_0 | RR_Rotate_180)) { + f_scale_dx = width; + scale_dx = F(width); + } + else { + f_scale_dx = height; + scale_dx = F(height); + } + } + if (rotation & RR_Reflect_Y) { + f_scale_y = -1; + scale_y = F(~0u); + if (rotation & (RR_Rotate_0 | RR_Rotate_180)) { + f_scale_dy = height; + scale_dy = F(height); + } + else { + f_scale_dy = width; + scale_dy = F(width); + } + } + + pixman_transform_scale(transform, &inverse, scale_x, scale_y); + pixman_f_transform_scale(f_transform, f_inverse, f_scale_x, f_scale_y); + pixman_transform_translate(transform, &inverse, scale_dx, scale_dy); + pixman_f_transform_translate(f_transform, f_inverse, f_scale_dx, + f_scale_dy); + } + +#ifdef RANDR_12_INTERFACE + if (rr_transform) { + if (!pixman_transform_multiply + (transform, &rr_transform->transform, transform)) + overflow = TRUE; + pixman_f_transform_multiply(f_transform, &rr_transform->f_transform, + f_transform); + pixman_f_transform_multiply(f_inverse, f_inverse, + &rr_transform->f_inverse); + } +#endif + /* + * Compute the class of the resulting transform + */ + if (!overflow && pixman_transform_is_identity(transform)) { + pixman_transform_init_translate(transform, F(x), F(y)); + + pixman_f_transform_init_translate(f_transform, x, y); + pixman_f_transform_init_translate(f_inverse, -x, -y); + return FALSE; + } + else { + pixman_f_transform_translate(f_transform, f_inverse, x, y); + if (!pixman_transform_translate(transform, &inverse, F(x), F(y))) + overflow = TRUE; + if (overflow) { + struct pixman_f_transform f_scaled; + + f_scaled = *f_transform; + RRTransformRescale(&f_scaled, 16384.0); + pixman_transform_from_pixman_f_transform(transform, &f_scaled); + } + return TRUE; + } +} diff --git a/nx-X11/programs/Xserver/randr/rrtransform.h b/nx-X11/programs/Xserver/randr/rrtransform.h new file mode 100644 index 000000000..2433a0f73 --- /dev/null +++ b/nx-X11/programs/Xserver/randr/rrtransform.h @@ -0,0 +1,79 @@ +/* + * Copyright © 2007 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _RRTRANSFORM_H_ +#define _RRTRANSFORM_H_ + +#include "randr.h" +#include "picturestr.h" + +typedef struct _rrTransform RRTransformRec, *RRTransformPtr; + +struct _rrTransform { + PictTransform transform; + struct pict_f_transform f_transform; + struct pict_f_transform f_inverse; + PictFilterPtr filter; + xFixed *params; + int nparams; + int width; + int height; +}; + +extern _X_EXPORT void + RRTransformInit(RRTransformPtr transform); + +extern _X_EXPORT void + RRTransformFini(RRTransformPtr transform); + +extern _X_EXPORT Bool + RRTransformEqual(RRTransformPtr a, RRTransformPtr b); + +extern _X_EXPORT Bool + +RRTransformSetFilter(RRTransformPtr dst, + PictFilterPtr filter, + xFixed * params, int nparams, int width, int height); + +extern _X_EXPORT Bool + RRTransformCopy(RRTransformPtr dst, RRTransformPtr src); + +/* + * Compute the complete transformation matrix including + * client-specified transform, rotation/reflection values and the crtc + * offset. + * + * Return TRUE if the resulting transform is not a simple translation. + */ +extern _X_EXPORT Bool + +RRTransformCompute(int x, + int y, + int width, + int height, + Rotation rotation, + RRTransformPtr rr_transform, + PictTransformPtr transform, + struct pict_f_transform *f_transform, + struct pict_f_transform *f_inverse); + +#endif /* _RRTRANSFORM_H_ */ diff --git a/nx-X11/programs/Xserver/randr/rrxinerama.c b/nx-X11/programs/Xserver/randr/rrxinerama.c index 31b750d64..9a164578f 100644 --- a/nx-X11/programs/Xserver/randr/rrxinerama.c +++ b/nx-X11/programs/Xserver/randr/rrxinerama.c @@ -87,15 +87,14 @@ #include "randrstr.h" #include "swaprep.h" +#include "panoramiXproto.h" #ifndef NXAGENT_SERVER -#include +#include "protocol-versions.h" #else -#include "panoramiXproto.h" +#define SERVER_RRXINERAMA_MAJOR_VERSION 1 +#define SERVER_RRXINERAMA_MINOR_VERSION 1 #endif -#define RR_XINERAMA_MAJOR_VERSION 1 -#define RR_XINERAMA_MINOR_VERSION 1 - /* Xinerama is not multi-screen capable; just report about screen 0 */ #define RR_XINERAMA_SCREEN 0 @@ -114,15 +113,17 @@ extern Bool noRRXineramaExtension; int ProcRRXineramaQueryVersion(ClientPtr client) { - xPanoramiXQueryVersionReply rep; - register int n; + int n; + + xPanoramiXQueryVersionReply rep = { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0, + .majorVersion = SERVER_RRXINERAMA_MAJOR_VERSION, + .minorVersion = SERVER_RRXINERAMA_MINOR_VERSION + }; REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.majorVersion = RR_XINERAMA_MAJOR_VERSION; - rep.minorVersion = RR_XINERAMA_MINOR_VERSION; if (client->swapped) { swaps(&rep.sequenceNumber, n); swapl(&rep.length, n); @@ -130,7 +131,7 @@ ProcRRXineramaQueryVersion(ClientPtr client) swaps(&rep.minorVersion, n); } WriteToClient(client, sizeof(xPanoramiXQueryVersionReply), (char *) &rep); - return (client->noClientException); + return Success; } int @@ -139,10 +140,11 @@ ProcRRXineramaGetState(ClientPtr client) REQUEST(xPanoramiXGetStateReq); WindowPtr pWin; xPanoramiXGetStateReply rep; - register int n, rc; + register int rc; ScreenPtr pScreen; rrScrPrivPtr pScrPriv; Bool active = FALSE; + int n; REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); #ifndef NXAGENT_SERVER @@ -151,6 +153,7 @@ ProcRRXineramaGetState(ClientPtr client) pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess); rc = pWin ? Success : BadWindow; #endif + if (rc != Success) return rc; @@ -161,39 +164,26 @@ ProcRRXineramaGetState(ClientPtr client) active = TRUE; } - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.state = active; - rep.window = stuff->window; + rep = (xPanoramiXGetStateReply) { + .type = X_Reply, + .state = active, + .sequenceNumber = client->sequence, + .length = 0, + .window = stuff->window + }; if (client->swapped) { swaps(&rep.sequenceNumber, n); swapl(&rep.length, n); swapl(&rep.window, n); } WriteToClient(client, sizeof(xPanoramiXGetStateReply), (char *) &rep); - return client->noClientException; -} - -static Bool -RRXineramaCrtcActive(RRCrtcPtr crtc) -{ - return crtc->mode != NULL && crtc->numOutputs > 0; + return Success; } static int RRXineramaScreenCount(ScreenPtr pScreen) { - int i, n; - - n = 0; - if (rrGetScrPriv(pScreen)) { - rrScrPriv(pScreen); - for (i = 0; i < pScrPriv->numCrtcs; i++) - if (RRXineramaCrtcActive(pScrPriv->crtcs[i])) - n++; - } - return n; + return RRMonitorCountList(pScreen); } static Bool @@ -208,9 +198,11 @@ ProcRRXineramaGetScreenCount(ClientPtr client) REQUEST(xPanoramiXGetScreenCountReq); WindowPtr pWin; xPanoramiXGetScreenCountReply rep; - register int n, rc; + register int rc; + int n; REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); + #ifndef NXAGENT_SERVER rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); #else @@ -220,18 +212,20 @@ ProcRRXineramaGetScreenCount(ClientPtr client) if (rc != Success) return rc; - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.ScreenCount = RRXineramaScreenCount(pWin->drawable.pScreen); - rep.window = stuff->window; + rep = (xPanoramiXGetScreenCountReply) { + .type = X_Reply, + .ScreenCount = RRXineramaScreenCount(pWin->drawable.pScreen), + .sequenceNumber = client->sequence, + .length = 0, + .window = stuff->window + }; if (client->swapped) { swaps(&rep.sequenceNumber, n); swapl(&rep.length, n); swapl(&rep.window, n); } WriteToClient(client, sizeof(xPanoramiXGetScreenCountReply), (char *) &rep); - return client->noClientException; + return Success; } int @@ -241,7 +235,8 @@ ProcRRXineramaGetScreenSize(ClientPtr client) WindowPtr pWin, pRoot; ScreenPtr pScreen; xPanoramiXGetScreenSizeReply rep; - register int n, rc; + register int rc; + int n; REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); #ifndef NXAGENT_SERVER @@ -250,19 +245,22 @@ ProcRRXineramaGetScreenSize(ClientPtr client) pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess); rc = pWin ? Success : BadWindow; #endif + if (rc != Success) return rc; pScreen = pWin->drawable.pScreen; - pRoot = WindowTable[pScreen->myNum]; - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.width = pRoot->drawable.width; - rep.height = pRoot->drawable.height; - rep.window = stuff->window; - rep.screen = stuff->screen; + pRoot = pScreen->root; + + rep = (xPanoramiXGetScreenSizeReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0, + .width = pRoot->drawable.width, + .height = pRoot->drawable.height, + .window = stuff->window, + .screen = stuff->screen + }; if (client->swapped) { swaps(&rep.sequenceNumber, n); swapl(&rep.length, n); @@ -272,30 +270,43 @@ ProcRRXineramaGetScreenSize(ClientPtr client) swapl(&rep.screen, n); } WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply), (char *) &rep); - return client->noClientException; + return Success; } int ProcRRXineramaIsActive(ClientPtr client) { xXineramaIsActiveReply rep; + int n; REQUEST_SIZE_MATCH(xXineramaIsActiveReq); - memset(&rep, 0, sizeof(xXineramaIsActiveReply)); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.state = RRXineramaScreenActive(screenInfo.screens[RR_XINERAMA_SCREEN]); + rep = (xXineramaIsActiveReply) { + .type = X_Reply, + .length = 0, + .sequenceNumber = client->sequence, + .state = RRXineramaScreenActive(screenInfo.screens[RR_XINERAMA_SCREEN]) + }; if (client->swapped) { - register int n; - swaps(&rep.sequenceNumber, n); swapl(&rep.length, n); swapl(&rep.state, n); } WriteToClient(client, sizeof(xXineramaIsActiveReply), (char *) &rep); - return client->noClientException; + return Success; +} + +static void +RRXineramaWriteMonitor(ClientPtr client, RRMonitorPtr monitor) +{ + xXineramaScreenInfo scratch; + + scratch.x_org = monitor->geometry.box.x1; + scratch.y_org = monitor->geometry.box.y1; + scratch.width = monitor->geometry.box.x2 - monitor->geometry.box.x1; + scratch.height = monitor->geometry.box.y2 - monitor->geometry.box.y1; + + WriteToClient(client, sz_XineramaScreenInfo, (char *) &scratch); } int @@ -303,58 +314,39 @@ ProcRRXineramaQueryScreens(ClientPtr client) { xXineramaQueryScreensReply rep; ScreenPtr pScreen = screenInfo.screens[RR_XINERAMA_SCREEN]; + int m; + RRMonitorPtr monitors = NULL; + int nmonitors = 0; + int n; REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); if (RRXineramaScreenActive(pScreen)) { - rrScrPriv(pScreen); - if (pScrPriv->numCrtcs == 0 || pScrPriv->numOutputs == 0) - RRGetInfo(pScreen); + RRGetInfo(pScreen, FALSE); + if (!RRMonitorMakeList(pScreen, TRUE, &monitors, &nmonitors)) + return BadAlloc; } - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.number = RRXineramaScreenCount(pScreen); - rep.length = rep.number * sz_XineramaScreenInfo >> 2; + rep = (xXineramaQueryScreensReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = bytes_to_int32(nmonitors * sz_XineramaScreenInfo), + .number = nmonitors + }; if (client->swapped) { - register int n; - swaps(&rep.sequenceNumber, n); swapl(&rep.length, n); swapl(&rep.number, n); } WriteToClient(client, sizeof(xXineramaQueryScreensReply), (char *) &rep); - if (rep.number) { - rrScrPriv(pScreen); - xXineramaScreenInfo scratch; - int i; - - for (i = 0; i < pScrPriv->numCrtcs; i++) { - RRCrtcPtr crtc = pScrPriv->crtcs[i]; - - if (RRXineramaCrtcActive(crtc)) { - int width, height; - - RRCrtcGetScanoutSize(crtc, &width, &height); - scratch.x_org = crtc->x; - scratch.y_org = crtc->y; - scratch.width = width; - scratch.height = height; - if (client->swapped) { - register int n; - - swaps(&scratch.x_org, n); - swaps(&scratch.y_org, n); - swaps(&scratch.width, n); - swaps(&scratch.height, n); - } - WriteToClient(client, sz_XineramaScreenInfo, (char *) &scratch); - } - } - } + for (m = 0; m < nmonitors; m++) + RRXineramaWriteMonitor(client, &monitors[m]); + + if (monitors) + RRMonitorFreeList(monitors, nmonitors); - return client->noClientException; + return Success; } static int @@ -383,9 +375,9 @@ ProcRRXineramaDispatch(ClientPtr client) static int SProcRRXineramaQueryVersion(ClientPtr client) { - REQUEST(xPanoramiXQueryVersionReq); - register int n; + int n; + REQUEST(xPanoramiXQueryVersionReq); swaps(&stuff->length, n); REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq); return ProcRRXineramaQueryVersion(client); @@ -394,9 +386,9 @@ SProcRRXineramaQueryVersion(ClientPtr client) static int SProcRRXineramaGetState(ClientPtr client) { - REQUEST(xPanoramiXGetStateReq); - register int n; + int n; + REQUEST(xPanoramiXGetStateReq); swaps(&stuff->length, n); REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); swapl(&stuff->window, n); @@ -406,9 +398,9 @@ SProcRRXineramaGetState(ClientPtr client) static int SProcRRXineramaGetScreenCount(ClientPtr client) { - REQUEST(xPanoramiXGetScreenCountReq); - register int n; + int n; + REQUEST(xPanoramiXGetScreenCountReq); swaps(&stuff->length, n); REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); swapl(&stuff->window, n); @@ -418,9 +410,9 @@ SProcRRXineramaGetScreenCount(ClientPtr client) static int SProcRRXineramaGetScreenSize(ClientPtr client) { - REQUEST(xPanoramiXGetScreenSizeReq); - register int n; + int n; + REQUEST(xPanoramiXGetScreenSizeReq); swaps(&stuff->length, n); REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); swapl(&stuff->window, n); @@ -431,9 +423,9 @@ SProcRRXineramaGetScreenSize(ClientPtr client) static int SProcRRXineramaIsActive(ClientPtr client) { - REQUEST(xXineramaIsActiveReq); - register int n; + int n; + REQUEST(xXineramaIsActiveReq); swaps(&stuff->length, n); REQUEST_SIZE_MATCH(xXineramaIsActiveReq); return ProcRRXineramaIsActive(client); @@ -442,9 +434,9 @@ SProcRRXineramaIsActive(ClientPtr client) static int SProcRRXineramaQueryScreens(ClientPtr client) { - REQUEST(xXineramaQueryScreensReq); - register int n; + int n; + REQUEST(xXineramaQueryScreensReq); swaps(&stuff->length, n); REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); return ProcRRXineramaQueryScreens(client); @@ -471,11 +463,6 @@ SProcRRXineramaDispatch(ClientPtr client) return BadRequest; } -static void -RRXineramaResetProc(ExtensionEntry * extEntry) -{ -} - void RRXineramaExtensionInit(void) { @@ -484,6 +471,9 @@ RRXineramaExtensionInit(void) return; #endif + if (noRRXineramaExtension) + return; + /* * Xinerama isn't capable enough to have multiple protocol screens each * with their own output geometry. So if there's more than one protocol @@ -494,6 +484,5 @@ RRXineramaExtensionInit(void) (void) AddExtension(PANORAMIX_PROTOCOL_NAME, 0, 0, ProcRRXineramaDispatch, - SProcRRXineramaDispatch, - RRXineramaResetProc, StandardMinorOpcode); + SProcRRXineramaDispatch, NULL, StandardMinorOpcode); } -- cgit v1.2.3