The branch, master has been updated via 6fc2884ae96a6665428a5b0463673a12dd8dae0b (commit) from 50b020b97cfd21a680d9857e3c5a277056b996c5 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6fc2884ae96a6665428a5b0463673a12dd8dae0b Author: Oleksandr Shneyder <oleksandr.shneyder@treuchtlingen.de> Date: Tue Oct 4 08:27:19 2011 +0200 New upstream version (3.5.0.5) - nx-X11-3.5.0-2 nxagent-3.5.0-5 nxauth-3.5.0-1 * New upstream version (3.5.0.5) - nx-X11-3.5.0-2 nxagent-3.5.0-5 nxauth-3.5.0-1 * status ----------------------------------------------------------------------- Summary of changes: CHANGELOG | 6 + CHANGELOG.NX.original | 12 + CHANGELOG.orig | 1085 ++++ VERSION | 2 +- CHANGELOG.X.original => WSDrawBuffer.h.X.original | 0 debian/changelog | 14 +- lib/X11/XKBMAlloc.c | 29 + lib/X11/XKBMAlloc.c.NX.original | 1023 ++++ lib/X11/{XKBMAlloc.c => XKBMAlloc.c.X.original} | 0 programs/Xserver/hw/nxagent/Args.c | 4 + programs/Xserver/hw/nxagent/Args.h | 2 + programs/Xserver/hw/nxagent/CHANGELOG | 19 + programs/Xserver/hw/nxagent/CHANGELOG.orig | 6326 ++++++++++++++++++++ programs/Xserver/hw/nxagent/Cursor.c | 26 +- programs/Xserver/hw/nxagent/Display.c | 2 + programs/Xserver/hw/nxagent/Display.c.orig | 2752 +++++++++ programs/Xserver/hw/nxagent/Events.c | 8 +- programs/Xserver/hw/nxagent/Extensions.c | 142 +- programs/Xserver/hw/nxagent/Imakefile | 8 +- programs/Xserver/hw/nxagent/Imakefile.orig | 222 + programs/Xserver/hw/nxagent/Init.c | 20 + programs/Xserver/hw/nxagent/Init.h | 2 + programs/Xserver/hw/nxagent/NXrandr.c | 1229 ---- programs/Xserver/hw/nxagent/NXrandr.c.NX.original | 1229 ---- .../Xserver/hw/nxagent/NXrandr.c.XF86.original | 1197 ---- programs/Xserver/hw/nxagent/Reconnect.c | 3 +- programs/Xserver/hw/nxagent/Screen.c | 230 +- programs/Xserver/hw/nxagent/Screen.h | 2 +- programs/Xserver/hw/nxagent/Window.c | 7 +- programs/Xserver/hw/nxagent/X/NXdixfonts.c | 3 +- programs/Xserver/hw/nxagent/X/NXrandr.c | 1344 ----- .../Xserver/hw/nxagent/X/NXrandr.c.NX.original | 1344 ----- .../Xserver/{randr => randr.X.original}/Imakefile | 0 .../Xserver/{randr => randr.X.original}/mirandr.c | 0 .../randr.c} | 0 .../Xserver/{randr => randr.X.original}/randrstr.h | 0 programs/Xserver/randr/Imakefile | 22 +- programs/Xserver/randr/Imakefile.NX.original | 36 + .../Xserver/randr/Imakefile.X.original | 0 programs/Xserver/randr/Makefile.am | 28 + programs/Xserver/randr/Makefile.in | 698 +++ programs/Xserver/randr/mirandr.c | 174 +- .../Xserver/randr}/panoramiXproto.h | 0 .../Xserver/randr/panoramiXproto.h.NX.original | 0 .../Xserver/randr/panoramiXproto.h.X.original | 0 programs/Xserver/randr/randr.c | 1320 +---- programs/Xserver/randr/randr.c.NX.original | 521 ++ programs/Xserver/randr/randr.c.X.original | 487 ++ programs/Xserver/randr/randr.h | 141 + programs/Xserver/randr/randr.h.NX.original | 141 + .../Xserver/randr/randr.h.X.original | 0 programs/Xserver/randr/randrproto.h | 655 ++ programs/Xserver/randr/randrproto.h.NX.original | 655 ++ .../Xserver/randr/randrproto.h.X.original | 0 programs/Xserver/randr/randrstr.h | 820 +++- programs/Xserver/randr/registry.h | 64 + programs/Xserver/randr/registry.h.NX.original | 64 + .../Xserver/randr/registry.h.X.original | 0 programs/Xserver/randr/rrcrtc.c | 984 +++ programs/Xserver/randr/rrcrtc.c.NX.original | 984 +++ programs/Xserver/randr/rrcrtc.c.X.original | 960 +++ programs/Xserver/randr/rrdispatch.c | 219 + programs/Xserver/randr/rrdispatch.c.X.original | 214 + programs/Xserver/randr/rrinfo.c | 335 ++ programs/Xserver/randr/rrmode.c | 420 ++ programs/Xserver/randr/rrmode.c.NX.original | 420 ++ programs/Xserver/randr/rrmode.c.X.original | 398 ++ programs/Xserver/randr/rroutput.c | 535 ++ programs/Xserver/randr/rrpointer.c | 145 + programs/Xserver/randr/rrproperty.c | 736 +++ programs/Xserver/randr/rrscreen.c | 1030 ++++ programs/Xserver/randr/rrscreen.c.NX.original | 1030 ++++ programs/Xserver/randr/rrscreen.c.X.original | 981 +++ programs/Xserver/randr/rrsdispatch.c | 398 ++ programs/Xserver/randr/rrxinerama.c | 490 ++ programs/Xserver/randr/rrxinerama.c.NX.original | 490 ++ programs/Xserver/randr/rrxinerama.c.X.original | 454 ++ 77 files changed, 27700 insertions(+), 7641 deletions(-) create mode 100644 CHANGELOG.orig mode change 120000 => 100644 VERSION copy CHANGELOG.X.original => WSDrawBuffer.h.X.original (100%) mode change 100755 => 100644 debian/rules mode change 100755 => 100644 debian/x2goagent.sh create mode 100644 lib/X11/XKBMAlloc.c.NX.original copy lib/X11/{XKBMAlloc.c => XKBMAlloc.c.X.original} (100%) create mode 100644 programs/Xserver/hw/nxagent/CHANGELOG.orig create mode 100644 programs/Xserver/hw/nxagent/Display.c.orig create mode 100644 programs/Xserver/hw/nxagent/Imakefile.orig delete mode 100644 programs/Xserver/hw/nxagent/NXrandr.c delete mode 100644 programs/Xserver/hw/nxagent/NXrandr.c.NX.original delete mode 100644 programs/Xserver/hw/nxagent/NXrandr.c.XF86.original delete mode 100644 programs/Xserver/hw/nxagent/X/NXrandr.c delete mode 100644 programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original copy programs/Xserver/{randr => randr.X.original}/Imakefile (100%) copy programs/Xserver/{randr => randr.X.original}/mirandr.c (100%) rename programs/Xserver/{hw/nxagent/X/NXrandr.c.X.original => randr.X.original/randr.c} (100%) copy programs/Xserver/{randr => randr.X.original}/randrstr.h (100%) create mode 100644 programs/Xserver/randr/Imakefile.NX.original copy CHANGELOG.X.original => programs/Xserver/randr/Imakefile.X.original (100%) create mode 100644 programs/Xserver/randr/Makefile.am create mode 100644 programs/Xserver/randr/Makefile.in copy {include/extensions => programs/Xserver/randr}/panoramiXproto.h (100%) copy include/extensions/panoramiXproto.h => programs/Xserver/randr/panoramiXproto.h.NX.original (100%) copy CHANGELOG.X.original => programs/Xserver/randr/panoramiXproto.h.X.original (100%) create mode 100644 programs/Xserver/randr/randr.c.NX.original create mode 100644 programs/Xserver/randr/randr.c.X.original create mode 100644 programs/Xserver/randr/randr.h create mode 100644 programs/Xserver/randr/randr.h.NX.original copy CHANGELOG.X.original => programs/Xserver/randr/randr.h.X.original (100%) create mode 100644 programs/Xserver/randr/randrproto.h create mode 100644 programs/Xserver/randr/randrproto.h.NX.original copy CHANGELOG.X.original => programs/Xserver/randr/randrproto.h.X.original (100%) create mode 100644 programs/Xserver/randr/registry.h create mode 100644 programs/Xserver/randr/registry.h.NX.original copy CHANGELOG.X.original => programs/Xserver/randr/registry.h.X.original (100%) create mode 100644 programs/Xserver/randr/rrcrtc.c create mode 100644 programs/Xserver/randr/rrcrtc.c.NX.original create mode 100644 programs/Xserver/randr/rrcrtc.c.X.original create mode 100644 programs/Xserver/randr/rrdispatch.c create mode 100644 programs/Xserver/randr/rrdispatch.c.X.original create mode 100644 programs/Xserver/randr/rrinfo.c create mode 100644 programs/Xserver/randr/rrmode.c create mode 100644 programs/Xserver/randr/rrmode.c.NX.original create mode 100644 programs/Xserver/randr/rrmode.c.X.original create mode 100644 programs/Xserver/randr/rroutput.c create mode 100644 programs/Xserver/randr/rrpointer.c create mode 100644 programs/Xserver/randr/rrproperty.c create mode 100644 programs/Xserver/randr/rrscreen.c create mode 100644 programs/Xserver/randr/rrscreen.c.NX.original create mode 100644 programs/Xserver/randr/rrscreen.c.X.original create mode 100644 programs/Xserver/randr/rrsdispatch.c create mode 100644 programs/Xserver/randr/rrxinerama.c create mode 100644 programs/Xserver/randr/rrxinerama.c.NX.original create mode 100644 programs/Xserver/randr/rrxinerama.c.X.original The diff of changes is: diff --git a/CHANGELOG b/CHANGELOG index 20aa2a2..3d3040f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,11 @@ ChangeLog: +nx-X11-3.5.0-2 + +- Fixed TR0202420. XKB utility functions wrote out of bounds. + +- Upgraded RandR server extension to version 1.2. + x2go-X11-3.5.0.2 - forked nx-X11-3.5.0-1 diff --git a/CHANGELOG.NX.original b/CHANGELOG.NX.original index 4faf2ad..ffbbe0a 100644 --- a/CHANGELOG.NX.original +++ b/CHANGELOG.NX.original @@ -1,5 +1,17 @@ ChangeLog: +nx-X11-3.5.0-2 + +- Fixed TR0202420. XKB utility functions wrote out of bounds. + +- Upgraded RandR server extension to version 1.2. + +nx-X11-3.5.0-1 + +- Opened the 3.5.0 branch based on nx-X11-3.4.0-4. + +- Updated copyright to year 2011. + nx-X11-3.4.0-4 - Fixed TR06H02359. Removed compiler warnings. diff --git a/CHANGELOG.orig b/CHANGELOG.orig new file mode 100644 index 0000000..ffbbe0a --- /dev/null +++ b/CHANGELOG.orig @@ -0,0 +1,1085 @@ +ChangeLog: + +nx-X11-3.5.0-2 + +- Fixed TR0202420. XKB utility functions wrote out of bounds. + +- Upgraded RandR server extension to version 1.2. + +nx-X11-3.5.0-1 + +- Opened the 3.5.0 branch based on nx-X11-3.4.0-4. + +- Updated copyright to year 2011. + +nx-X11-3.4.0-4 + +- Fixed TR06H02359. Removed compiler warnings. + +nx-X11-3.4.0-3 + +- Updated copyright to year 2010. + +nx-X11-3.4.0-2 + +- Fixed TR04G02208. Added a path to rgb file. + +nx-X11-3.4.0-1 + +- Opened the 3.4.0 branch based on nx-X11-3.3.0-7. + +- Updated copyright to year 2009. + +nx-X11-3.3.0-7 + +- Fixed TR08G02257. The maximum client condition was reached because + available fd exhausted. This bug was caused by a function in font + library not closing the file before a return on error breaking the + flow of normal execution. + +- Fixed TR06G02225. The implementation of Xvprintf() has been reviewed + to work on more platforms. Previous implementation caused a failure + in the build of keyboard map on some platform like Solaris 8 and 9. + +nx-X11-3.3.0-6 + +- Fixed TR03G02198. Reimplemented Xvprintf() in Xserver/os to handle + the case in which vsnprintf returned -1. + +- Returning from _XSeqSyncFunction() and _XReply() if an I/O error is + detected. + +nx-X11-3.3.0-5 + +- Fixed TR01G02163. Signals need to be blocked before the call to + fork() in the Popen() utility. + +- Fixed TR01G02164. Trapezoid data need to be validated before use. + This issue was the same of CVE-2007-2437. + +nx-X11-3.3.0-4 + +- Enabled the code resetting the Xlib buffer if an IO error occured. + +nx-X11-3.3.0-3 + +- Fixed the search path for the XKB base directory. + +nx-X11-3.3.0-2 + +- Fixed TR10F02116. The X11 agent could enter an indefinite wait state + if connection to X display is broken and libX11 output buffer is not + empty. + +nx-X11-3.3.0-1 + +- Opened the 3.3.0 branch based on nx-X11-3.2.0-2. + +nx-X11-3.2.0-2 + +- Imported patch fixing issues from X.Org security advisory, June + 11th, 2008: Multiple vulnerabilities in X server extensions. CVE + IDs: CVE-2008-1377, CVE-2008-1379, CVE-2008-2360, CVE-2008-2361, + CVE-2008-2362. + +nx-X11-3.2.0-1 + +- Opened the 3.2.0 branch based on nx-X11-3.1.0-6. + +nx-X11-3.1.0-6 + +- Modified Xserver Imakefile to link the Xfixes library. + +nx-X11-3.1.0-5 + +- Disabled the terminate action, just in case the TerminateServer + symbol is binded to a non default key sequence. + +nx-X11-3.1.0-4 + +- Imported patch fixing issues from X.Org security advisory, January + 17th, 2008: Multiple vulnerabilities in the X server. CVE IDs: + CVE-2007-5760 CVE-2007-5958 CVE-2007-6427 CVE-2007-6428 + CVE-2007-6429 CVE-2008-0006. + +nx-X11-3.1.0-3 + +- Moved a variable definition placed in _mesa_make_current(). + +nx-X11-3.1.0-2 + +- Fixed TR10E01924. A crash could occur in _mesa_make_current(). + +- Initialized after_ret variable in _XcmsGetProperty(). + +nx-X11-3.1.0-1 + +- Opened the 3.1.0 branch based on nx-X11-3.0.0-37. + +nx-X11-3.0.0-37 + +- Changed the Xserver Imakefile to link against Xcomposite on the + Cygwin platform too. + +nx-X11-3.0.0-36 + +- Fixed TR07E01806. Modified host.def to build GLX code with symbol + __GLX_ALIGN64 defined on Solaris platform. + +nx-X11-3.0.0-35 + +- Flush explicitly the NX link before entering the select() in the + WaitForReadable() and WaitForWritable() routines. + +nx-X11-3.0.0-34 + +- Changed the agent Imakefile to link to the Xcomposite library. + +nx-X11-3.0.0-33 + +- Fix the NX_TRANS_WAKEUP stuff in WaitForSomething() to not over- + ride a valid timeout. + +- Check if the requesting client is gone in the XFixes functions + sending the cursor events. + +nx-X11-3.0.0-32 + +- Define DDXOSVERRORF and DDXOSFATALERROR symbols on Sun. + +- Changed the copyright attribution from Medialogic to NoMachine. + +nx-X11-3.0.0-31 + +- Make SmartScheduleStopTimer() visible outside Xserver/os/utils.c + so that it can be called by the agent. Export the declaration in + dixstruct.h. + +nx-X11-3.0.0-30 + +- The OsVendorVErrorFFatal flag is set to 1 if the function pointed + by OsVendorVErrorFProc is called due to a fatal error. + +- Give the possibility to the agent to redirect the standard error + during a Popen() or a System() by setting the OsVendorStartRedir- + ectErrorFProc and OsVendorEndRedirectErrorFProc function pointers. + +nx-X11-3.0.0-29 + +- Changed the default message printed on a fatal server error. The + new message is: + + Error: Aborting session with 'Error text...'. + +- Hacked LogVWrite() to force all fatal error messages to have an + uppercase initial. Also remove the trailing newline and the full- + stop, if present. + +nx-X11-3.0.0-28 + +- Corrected the typos in the ChangeLog. + +nx-X11-3.0.0-27 + +- Fixed the cleanup of the X_RenderCompositeText16 padding bytes. + +- More code cleanup in the NX changes to the Xrender library. + +- Changed host.def to build the freetype and fontconfig libraries + if the agent server is also built. Freetype is built as a shared + library: this avoids the link error on 64 bit platforms. + +nx-X11-3.0.0-26 + +- Applied the following security patches, from the X.Org security + advisory, April 3rd, 2007 "Multiple vulnerability in X server, + libXfont and libX11": + + xorg-xserver-1.2.0-xcmisc.diff + xorg-libXfont-1.2.7-bdf-fontdir.diff + xorg-libX11-1.1.1-xinitimage.diff + +nx-X11-3.0.0-25 + +- Added the missing *.X.original file for ChkIfEv.c and Xlib.h. + +nx-X11-3.0.0-24 + +- Changed Xrender to clean up the padding bytes in XRenderComposite- + Text functions. + +- Added function XRenderCleanGlyphs() cleaning the padding bytes in + the data section of RenderAddGlyphs requests. + +nx-X11-3.0.0-23 + +- Removed the additional parameter from the call to NXTransFlush() + in _XReply(). + +- Call NXTransExit() on AbortServer() (called by FatalError()) to + give the proxy a chance to shut down the NX transport. + +nx-X11-3.0.0-22 + +- Moved the replacement of XCheckIfEvent() ChkIfEv.c with the name + XCheckIfEventNoFlush(). + +nx-X11-3.0.0-21 + +- Set BUFSIZE to 8192 bytes. While the output buffer size can be + configured by setting the XLIBBUFFERSIZE in the environment (see + OpenDis.c), this constant is still used when reading from the + socket. + +nx-X11-3.0.0-20 + +- If set, the handler pointed by _NXDisplayWriteFunction is called + after that more data is written to the display connection. + +nx-X11-3.0.0-19 + +- Added a RejectWellKnownSockets() stub to make possible to compile + the agent when the NX transport is disabled. + +- Added more useful logs to _XWaitForWritable(). + +nx-X11-3.0.0-18 + +- Changed Imakefile of X11 and Xserver in order to build nxcompshad + just before the NX agent server. + +- Changed Imakefile in Xserver to add NXdamage.o to NXAGENTOBJS. + +nx-X11-3.0.0-17 + +- Changed host.def in order to build Xdamage and Xrandr libraries. + +- Changed host.def in order not to build NXWin. + +nx-X11-3.0.0-16 + +- Changed host.def in order to build Xtst as a shared library. + +nx-X11-3.0.0-15 + +- Changes to comply with nxcompshad library. + +- Changed configuration to statically build Xtst library. + +- Restored parser directory under Xserver/hw/xfree86. + +nx-X11-3.0.0-14 + +- Changed the LICENSE file to state that the software is only made + available under the version 2 of the GPL. + +- Added file COPYING. + +- In nx-X11/programs and nx-X11/programs/Xserver/hw/xfree86, removed + files and directories not needed to build servers. + +nx-X11-3.0.0-13 + +- Changes aimed to link servers with static versions of Xdmcp and Xau + libraries. + +nx-X11-3.0.0-12 + +- Added references to implented FR in the ChangeLog. + +- Removed nx-X11/fonts and nx-X11/doc directories. They are not needed + for building the NX components. + +nx-X11-3.0.0-11 + +- Updated the copyright notices to year 2007. + +nx-X11-3.0.0-10 + +- Applied the following security patches: + + x11r6.9.0-cidfonts.diff + x11r6.9.0-dbe-render.diff + x11r6.9.0-geteuid.diff + x11r6.9.0-mitri.diff + x11r6.9.0-setuid.diff + +nx-X11-3.0.0-9 + +- Merged the NX changes to X11 with the X11R6.9.0 version of X.org. + +nx-X11-3.0.0-8 + +- Changes to build Xshadow library when building X11. + +- Changes to Xserver Imakefile to link Xshadow library. + +- Changes to host.def in order to build on old distributions. + +nx-X11-3.0.0-7 + +- Imported changes up to nx-X11-2.1.0-2 + +- Fixed TR08D01485. Updated rgb file paths validation in order to + support Ubuntu distribution. + +- Added Xtst to libraries to be linked by nxagent. + +- Changed Xpm Imakefile to build a shared library on Solaris. + +- Fixed build error on Solaris in xtrans. + +- Changed host.def not to build Xnest server. + +- Changed Xserver Imakefile to link nxaccess library. + +nx-X11-3.0.0-6 + +- Added the path of nxaccess library to the server link command. + +nx-X11-3.0.0-5 + +- Implemented FR10C01079 and FR10C01080. The merge of NX changes to + the X.org code is complete. + +- Merged changes in config/cf. The NX-*.def files have been dismissed. + Main platform dependent configurations have been moved to host.def. + +- Removed *.reference files from config/cf. + +- Fixed compilation for Cygwin platform. + +nx-X11-3.0.0-4 + +- Imported all changes up to nx-X11-2.0.0-32. + +- Cleaned up lib/zlib directory. + +- Added missing file programs/Xserver/os/utils.c.NX.original. + +- Updated the copyright notice to year 2006. + +- The pointer to the display buffer is reset after an I/O error. + This prevents leaving the buffer in an inconsistent state if the + error occurs inside _XFlush(). + +- Removed the modifications to the Xrender library. The cleanup of + the padding bytes is now performed by the NX transport. + +- NX uses the updated ZLIB from its build tree, so Imake.tmpl will + now assume that the platform as ZLIB unless otherwise stated. + +- The path of the SecurityPolicy file is searched and validated at + runtime. + +- Added the _X11TransSocketProxyConnInfo() function to Xtranssock.c + It returns the pointer to the XtransConnInfo private, if it is a + valid _NXProxyConnInfo structure. + +- The above function is used by OpenDis.c to detect if the NX trans- + port was requested on the display and avoid spurious error messa- + ges in the case of a connection failure. + +- Added NXmiwindow.o to the NXAGENTOBJS in the Xserver's Imakefile + and imported NXmiwindow.c in nxagent. This allows us to check the + pointer to the pOldClip region in miSetShape() before going on + freeing it. + +- The path of the XKB base directory and of the xkbcomp comand is + validated at runtime. + +- Also added a check to verify the validity of the rgb file path. + +- Added NXresource.o to NXAGENTOBJS in the Imakefile of nxagent. We + need this to a assign a resource to the pixmaps and other server + objects which need to be enumerated at reconnection. Some objects, + being created by the X server and not by the clients, don't pass + through the resource assignment process operated by the dix. To + ensure that all objects get a resource, we add a resource at the + time the object is created and temporarily assign the resource to + the server client. If the dix later assigns the resource to a va- + lid client, the resource is removed from the server client's list. + +- The display block handler registered by the client is called in + WaitForReadable() and WaitForWritable() before every select(), + not only upon entering the function. The reason is that more + data can be possibly produced for the NX link by the proxy it- + self and, when setting the flush policy to deferred, the client + may not have the chance of flushing the NX link. + +- Fixed a bug in XkbUseExtension() that caused Xlib to query the + presence of the XKEYBOARD extension multiple times. This partial- + ly implents the FR01D01275. The complete implementation required + modifications to the X11 agent, implemented in nxagent-2.0.0-33. + +- Updated to comply with the new NXTransFlush() interface. + +- Both nxwin and nxagent now read the X authority file by using an + fopen() instead of the system command 'cat'. + +- Removed NXmiwindow.o from the NXAGENTOBJ list. The agent will now + use the original miwindow.c. + +- Added some additional logs in Xtranssock.c to follow the creation + and removal of the X server's Unix listener. + +- Avoided the sleep of 5 seconds forced by Xtransutil.c if the dir- + ectory where the Unix listener is created is not owned by root. + This sleep is not executed on Cygwin (where the X socket can be + hardly owned by root) but may delay the startup of the agent if + the user chose a different NX_TEMP directory. Furthermore, it is + unclear what real benefits such sleeps are intended to bring to + the security of the X server. This can be controlled by defining + the NX_TRANS_SLEEP directive in Xserver/os/Imakefile. + +- Added NXmiexpose.o to the NXAGENTOBJ. + +- Ensured that _X11TransSocketCloseConnInfo() now initiates the NX + shutdown by calling NXTransClose(). + +- Corrected a misplaced #else that made SocketUNIXConnect() skip a + block if the connection was not to the NX transport. + +- Updated to comply with the new NX function prototypes introduced + in nxcomp-2.0.0-31. + +- Moved the most important Xtranssock.c modifications into separate + functions. + +- Ensured that the modifications enabling the internal connections + to the proxy are compiled only when the TRANS_CLIENT directive is + defined. + +- Solved a bug that prevented the X11 socket to be deleted at the X + server shutdown. This needs further tests. + +- Added nxcompext to the link of nxagent, now that the dependency + of libX11 from nxcompext is removed. + +- Improved the Xtranssock routines to never loop through the array + of connection info. + +- Added a congestion flag to the connection info structure and a + function querying the transport and reporting if a change in the + congestion state has occurred. The code is currently not enabled, + because instead of polling the transport, we let the proxy notify + the changes in congestion state by using the callback. The code + can be used in future to extend the library, for example, by add- + ing some counters tracking the bandwidth usage of the socket con- + nection, so that we can make the congestion notifications work + even with a plain X11 connection. + +- Profiled the routines in XlibInt.c to reduce the number of calls + to the error predicate function provided by the client. + +- Fixed the nxcompext build problem that caused make World to fail. + +- Added a 'CONF' target to the X11 and Xext Imakefiles so that the + configure script is not run if the config.status exists. + +- Added the _NXDisplayBlockHandler hook. The function is called by + Xlib before blocking. The parameter says if Xlib is going to wait + for more input or because it needs to write to the display socket. + The client can use the hook to perform any internal operation that + may require some time to complete. The user, though, should not + try to read or write to the display inside the callback routine. + +- Removed the outdated NX_TRANS_PROCESS, NX_TRANS_THREAD and NX_TR- + ANS_INCLUDE defines. + +- Reverted the lib/Xext Imakefile to the original XF86 version and + moved the build of the nxcompext library among the libX11 depend- + encies. + +- Corrected the lib/X11 Imakefile so that a new build of nxcomp and + nxcompext is not attempted if the libraries are up-to-date. + +- Removed the unused display buffer and image cleanup functions. + +- Reverted the PutImage.c file to the original XF86 version. + +- Added the _NXDisplayErrorPredicate function in XlibInt.c. It is + actually a pointer to a function called whenever Xlib is going to + perform a network operation. If the function returns true, the + call will be aborted and Xlib will return the control to the ap- + plication. It is up to the application to set the XlibDisplayIO- + Error flag after the _NXDisplayErrorPredicate returns true. The + function can be used to activate additional checks, besides the + normal failures detected by Xlib on the display socket. For exam- + ple, the application can set the funciton to verify if an inter- + rupt was received or if any other event occurred mandating the + end of the session. + +- Modified XIfEvent(), XMaskEvent() and XPeekIfEvent() to check the + _NXDisplayErrorPredicate function and return immediately if the + function returns true. + +- Modified _XWaitForReadable() to never enter the loop if the dis- + play is broken. + +- Corrected a make problem on Windows that caused the nxcomp and + nxcompext libraries to be referred with the wrong name, with the + result that a new configure and make was attempted at each build + attempt. + +- Merged all the changes to os, Xext, xkb, dix. + +- Changed host.def to build only the agent server. + +- Merged the changes to Xtranssock.c + +nx-X11-3.0.0-3 + +- Merged the changes to lib/X11. Restored original PutImage.c and + ClDisplay.c files. + +nx-X11-3.0.0-2 + +- Created a directory named 'reference' to keep files that are chan- + ged during the development of nx-X11 since the 1.5.0-16 to 2.0.0-32 + version. These files will be removed as long as the differences are + merged to the 3.0.0 version. When all differences are merged, this + directory will be removed. + +nx-X11-3.0.0-1 + +- Opened the 3.0.0 branch based on the nx-X11-2.0.0-9. The 3.0.0 + branch will now support the migration toward the X.org tree. Due + to time concerns, the 2.0.0 branch is going to be based on the + same nx-X11 as the 1.5.0. + +nx-X11-2.0.0-9 + +- Modified the agent link arguments to explicitly include the NX + libraries. + +- Disabled the Xinerama extension to avoid further clashes with + the redefinition of GC in Xlib. + +- Added os/libos.a at the end of the agent link. + +nx-X11-2.0.0-8 + +- Moved the declarations of _NXEnable* and related structures from + Xlibint.h to NXlibint.h. + +- Added provision for building the agent. This can be controlled by + setting NXAgentServer to YES in host.def. + +- Setting the NXUpgradeAgentServer variable to YES in the host.def + file will make the agent assume that it is being built in the new + environment. This variable is normally unset when building in the + 1.5.0 tree. + +nx-X11-2.0.0-7 + +- Fixed a problem on AMD64 due to the size of the area pointed by + the argument of _X11TransBytesReadable(). BytesReadable_t is long, + at least on Linux, while the ioctl() requires a pointer to an int. + The original _X11TransBytesReadable() function simply calls the + ioctl() by passing the pointer that is provided. NXTransReadable(), + instead, was correctly returning the value assuming a pointer to + a long, but this crashes some applications, among them xterm. Now + NXTransReadable() follows the same schema of the ioctl() call and + stores the result assuming a pointer to an int. + +- Removed the outdated NX_TRANS_PROCESS and NX_TRANS_THREAD code. + +nx-X11-2.0.0-6 + +- Made xterm work with the NX transport. This required small changes + to the Xt toolkit's and the xterm's files to let them use the NX + aware select(). This is useful to test the NX transport until the + nxagent server is integrated. + +- When the transport is gone _X11TransSocketBytesReadable() returns + EPIPE. This makes the client become aware of the closure of the + connection. + +- Added a call to NXTransDestroy() in XCloseDisplay(). + +- The exit() function in XlibInt.c causes a call to NXTransExit(). + +- Merged changes to dix/pixmap.c, xkb/xkbDflts.h, mi/Imakefile. + +- Removed unneeded changes and files containing patches already in + the latest X.org distribution: dix/dispatch.c, fb/fbcompose.c, fb/ + fbgc.c, xkb/ddxList.c, font/fontfile/dirfile.c, font/fontfile/ + encparse.c, font/fontfile/fontfile.c, font/FreeType/fttools.c, + Xrender/FillRect.c, Xrender/Picture.c. + +nx-X11-2.0.0-5 + +- Changes to the lib/X11/Imakefile to cleanly build the tree. This + is obtained by creating a link to the Xcomp library in exports/lib + without having to modify the programs' Imakefiles. + +- Finished merging the NX changes in the lib/X11 files. + +- Merged the CHANGELOG with the one from the 1.5.0 tree. + +nx-X11-2.0.0-4 + +- Merged the NX changes in most Xtrans and lib/X11 files. + +nx-X11-2.0.0-3 + +- Temporarily disabled the use of the MMX extensions in the Xserver's + fb code to successfully compile with GCC 4. + +nx-X11-2.0.0-2 + +- Imported the *.NX.reference and *.XF86.reference files that will + be needed for the merge. These files are the *.original from the + 1.5.0 tree. They will be removed as long as the merge advances. + +nx-X11-2.0.0-1 + +- Created the 2.0.0 branch based on X.org the 6.8.99.16 snapshot. + +nx-X11-1.5.0-16 + +- Added the missing *.XF86.original and *.NX.original files. + +nx-X11-1.5.0-15 + +- Made the nxagent server use select() instead of poll() on Solaris + so that it can leverage the new NX transport. + +- Moved the NXTransFlush() call to _XReply(). + +nx-X11-1.5.0-14 + +- Added the 'synchronous' parameter in the _XWaitForReadable() call + to NXTransFlush(). + +nx-X11-1.5.0-13 + +- Removed the log entry in XlibInt.c on calling the NXTransFlush(). + +nx-X11-1.5.0-12 + +- Changed XlibInt.c and utils.c to call NXTransExit(). + +nx-X11-1.5.0-11 + +- Changed XlibInt.c to comply with the new NXTransFlush() interfa- + ce introduced in nxcomp-1.5.0-42. + +- Cosmetic changes to messages printed for debug. + +nx-X11-1.5.0-10 + +- Ensured that all calls to _XIOError() are followed by a return. + +- Put exiting the client program in the case of an I/O error under + the control of the _NXContinueOnDisplayError flag. If set, the + I/O error routine will simply return, leaving to the application + the responsibility of checking the state of the XlibDisplayIOEr- + ror flag. + +- Added some checks whenever a read or write is performed on the X + connection, so that we can exit the I/O loop if the X channel is + gone. It is likely that more work will be needed when trying to + support XTHREADS enabled connections. This should not be a pro- + blem for now, as the default is still to quit the application un- + less the _NXContinueOnDisplayError flag is explicitly set. + +nx-X11-1.5.0-9 + +- Removed the references to the cygipc library in NXWin. Now use the + cygserver daemon to provide the MIT-SHM extension. + +- Fixed an error in the UseCygIPC definition. + +- Changed the cygwin.cf file to avoid redefinition of the BuildGlxExt, + XWinServer and BuildGlxExt symbols. + +nx-X11-1.5.0-8 + +- Added provision for deferred writes in the NX transport. When en- + tering _XWaitForReadable() we must ensure that data is flushed to + the proxy link. + +- Added the UseCygIPC define to NX-Cygwin.def. + +- Updated the NoMachine copyright notice on the modified files. + +nx-X11-1.5.0-7 + +- Added the GLX extension in NX-Sun.def. + +- Added some more logs in WaitFor.c. + +nx-X11-1.5.0-6 + +- Modified Xlibint.h and XlibInt.c to remove the _NXFlushSize para- + meter. New agents run the NX transport in-process, so we don't get + any benefit from increasing the display buffer size. + +- Modified NX-Darwin.def to not build the NXDarwin server. Since the + 1.4.0 version the NXDarwin server is unsupported and the NX client + for the Mac requires that the Apple X server is installed. + +- Changed NX-Linux.def to avoid the warning due to "SharedLibGLw" + being not defined. + +nx-X11-1.5.0-5 + +- Modified the Xserver Imakefile to link nxagent with FbPostFbLibs + and avoid including mfb/libmfb.a. + +- Added the GLX extension in NX-Linux.def. This provides unaccelera- + ted support in nxagent, with GLX operations translated into core X + protocol primitives. + +- Fixed x-X11/programs/Xserver/GL/dri/Imakefile to look in ../../hw/ + /xfree86/os-support/bus for includes. + +nx-X11-1.5.0-4 + +- Avoid calling NXTransSelect() if the transport is gone, so that we + don't have to wait until the timeout. + +- Added the "-fno-strict-aliasing" option to linux.cf when compiling + with a GCC version >= 4. In the words of Stefan Dirsch: "The opt- + ion, which is default since gcc 3.1, can result in wrong code when + the gcc warnings related to it are ignored. And as there are seve- + ral warnings in X11 related to it, it has been disabled for X11 + from the beginning. This didn't change for gcc4, so it still needs + to be used." + +- Added more logs in XlibInt.c and utils.c. A warning is printed if + the SmartScheduler is initialized. + +nx-X11-1.5.0-3 + +- Started integration of nxcomp with the X libraries. The Xtrans + code creates an internal connection to the nxcomp library instead + of a child proxy process. + +- Changed Xpoll.h and XlibInt.c to replace the standard Select + with a version giving NX a chance to check its own descriptors. + +- Implemented the NXTransReadVector() and the NXTransWriteVector() + functions to replace READV() and WRITEV(). + +- Implemented memory-to-memory communication with the NX proxy by + making use of the NXTransAgent() interface. + +nx-X11-1.5.0-2 + +- We think that the way LoadAuthorization() is working is wrong. + It doesn't reset the list of stored authorizations before reading + the new cookies. Our take is that if a new auth file is to be + read, the only cookies that are to be accepted are those that are + in the new file, not those in the file -plus- those that have + been in the file in the past. Furthermore, if the list can't be + read or it is empty, it should assume that it ignores which co- + okies are valid and thus it should disable any access. Your mile- + age can vary. A less draconian approach could be to leave the old + cookies if the file can't be read and remove them only if the + file is empty. + + Adding the cookies without removing the old values for the same + protocol has an important implication. If an user shares the co- + okie with somebody and later wants to revoke the access to the + display, changing the cookie will not work. This is especially + important with NX. For security reasons, after reconnecting the + session to a different display, it is advisable to generate a + new set of cookies, but doing that it is useless with the current + code, as the old cookies are going to be still accepted. On the + same topic, consider that once an user has got access to the X + server, he/she can freely enable host authentication from any + host, so the safe behaviour should be to reset the host based + authenthication at least at reconnection, and keep as valid only + the cookies that are actually in the file. This behaviour would + surely break many applications, among them a SSH connection run + inside a NX session, as ssh -X reads the cookie for the display + only at session startup and does not read the cookies again + when the auth file is changed. + + Another bug (or feature, depending on how you want to consider + it) is that if the authority file contains entries for different + displays (as it is the norm when the authority file is the default + .Xauthority in the user's home), the X server will match -any- of + the cookies, even cookies that are not for its own display. This + means that you have to be careful when passing an authority file + to nxagent and maybe keep separate files for letting nxagent find + the cookie to be used to connect to the remote display and for + letting it find what cookies to accept. If the file is the same, + clients will be able to connect to nxagent with both the cookies. + This bug obviously affects any X server, also the real X server + running on the workstation, so it is common to see nxagent being + able to connect to the X server even if no cookie matches the + real display. + +- Added a check in lib/Xau/AuRead.c to prevent the fread() call to + be interrupted by SIGCHLD while reading the auth file. Due to the + way the old code worked, this could lead to the server enabling + local host access to the display. This problem had been identified + in the past. We just found that all the code dealing with reading + the auth file was affected. The code calls sigprocmask() to block + the signal (though it leaves some other calls unprotected) but the + SIGCHLD was not included in the set. + +- Added SIGCHLD to the set of signals that are blocked when reading + the authorization file. + +- As I was at it, I changed the path to the SecurityPolicy file. A + few Linux ditributors ship the file in $LIBDIR/xserver, a few only + in /etc/X11/xserver, most others in both places. It seems that + those who ship in $LIBDIR/xserver do also in /etc/X11 but the op- + posite is not true, so I switched to /etc/X11. + +nx-X11-1.5.0-1 + +- Opened the 1.5.0 branch. + +nx-X11-1.4.1-2 + +- Set parameter UseCygIPC on cygwin conf file in order to force the + build of MIT-SHM estension. + +- Removed some spurius object file. + +nx-X11-1.4.1-1 + +- Opened the 1.4.1 branch. + +nx-X11-1.4.0-8 + +- Changed DefaultFontPath and DefaultRGBDatabase in + NX-Cygwin.def. + +nx-X11-1.4.0-7 + +- Imported dispatch in nxdarwin package, in order to let + nxdarwin being able to detect new client connection. + +- Changed the Xpm Imakefile to make also .a static library + on Solaris. To link nxviewer and nxdestkop staticaly. + +nx-X11-1.4.0-6 + +- XInput extension enabled on MacOSX. + +- Added some missing backup files of the original XFree86 + package. + +nx-X11-1.4.0-5 + +- Changed the mi Imakefile in order to let xfree86 servers use + the normal mi extension initialization for the XInput exten- + sion. + +- XInput extension enabled on Solaris. + +nx-X11-1.4.0-4 + +- Removed the RejectWellKnownSocket for the cygwin and + MacOSX environments that doesn't use the Xtransport library. + +nx-X11-1.4.0-3 + +- Changed the implementation of the reject method in the + Xtransport library, now close any new incoming connection + immediately without reading or writing to it. + +nx-X11-1.4.0-2 + +- Implemented a reject method in the Xtransport library, + this function accept and close every connection attempt, + on the specified listening socket. + +- Added the new function RejectWellKnownSocket to the os + connection code. + This function use the new transport reject function on + all listening socket. + +nx-X11-1.4.0-1 + +- Opened the 1.4.0 branch. + +- Removed forgotten nxagent-1.3.2-20 directory. + +nx-X11-1.3.2-9 + +- Prevents NX Darwin server going through the reset. On Darwin + we found that the it is not possible to get the correct key- + board layout unless it is set on the local machine, before + the NX session is started, by using xmodmap. As we set the + keyboard locally, we must prevent the X server to reset, or + we would loose any local configuration. + +nx-X11-1.3.2-8 + +- Removed action associated to keysym XK_Terminate_Server. This + could cause agent to be terminated when pressing shift + back- + space if using the default US keyboard mapping. + +- Disabled the remaining debug logs in lib/X11/PutImage.c + +nx-X11-1.3.2-7 + +- Fixed the wrong programs/Xserver/Imakefile in 1.3.2-6 package. + +nx-X11-1.3.2-6 + +- Changed the define from NX_CLEAN_IN_PLACE to NX_CLEAN_INPLACE. + Definition of symbol is now placed in the Imakefile. + +- The new _NXEnableCleanInplace Xlib variable does control which + algorithm is used to clean the images. Setting NX_IMAGEINPLACE + in the environment will activate the in-place cleanup. + +- The default value of _NXEnableCleanInplace is -1. Leaving it to + a value <= 0 disables use of CleanInplace. + +nx-X11-1.3.2-5 + +- Patch in config/cf/sun.cf. Fix for libfontconfig compilation + during gmake Everything on Solaris. + +- Patch in lib/X11/Imakefile. Fix for nxcomp compilation during + gmake World on Solaris. + +nx-X11-1.3.2-4 + +- Image cleanup is now performed by using NXCleanInPlaceImage from + nxcompext. This function saves a buffer copy by cleaning the + padding bytes in the same buffer provided by the caller. Note that + to prevent memory violations in the case the image was allocated + in a static buffer, the function will temporarily redefine the + SIGSEGV handler. The former handler is restored before returning + to the caller. This can potentially affect some multithreaded + clients. Is to be decided if the function is safe enough to be + included in the production release. + +nx-X11-1.3.2-3 + +- More debug logs in programs/Xserver/xkb/ddxLoad.c. + +nx-X11-1.3.2-2 + +- Added NXmiwindow.o to NXAGENTOBJS in programs/Xserver/Imakefile. + File was not linked into the resulting nxagent. This solves the + problem of missing repaints in CDE and other Xt applications. + +nx-X11-1.3.2-1 + +- Added some debug logs in programs/Xserver/xkb/ddxLoad.c. Function + XkbDDXCompileKeymapByNames is called by OpenOffice to read the + keyboard configuration whenever a drop-down menu is accessed. It + seem to always fail with the following error: + + The XKEYBOARD keymap compiler (xkbcomp) reports: + > Error: Can't find file "unknown" for geometry include + > Exiting + > Abandoning geometry file "default" + +- Opened the 1.3.2 development branch. + +nx-X11-1.3.1-12 + +- Fixed a problem in xkb/ddxLoad.c on Solaris where Pclose was + always returning an error code despite the fact that command + was executed properly. + +nx-X11-1.3.1-11 + +- Changed default GCC flags from '-O2 -fno-strength-reduce' to + -O3. No platform where NX is targeted is currently using a + GCC 2.x affected by the -fno-strength-reduce bug. Note also + that nxcomp is already compiled with -O3 since 1.1.1, so it + can be considered safe. + +nx-X11-1.3.1-10 + +- Imported an updated fbcompose.c file from XFree86-4.3.99.902. + This fixes "uninitialized value" problems reported by Valgrind. + +- Fixed further buffer overflows by updating the following file + with recent versions coming from the XFree86-4.3.99.902 tree. + + nx-X11/lib/font/fontfile/dirfile.c + nx-X11/lib/font/fontfile/encparse.c + nx-X11/lib/font/fontfile/fontfile.c + +- Fixed a possible buffer overflow in lib/font/FreeType/fttools.c. + Verified that the change is already in the XFree86 4.4.0 CVS. + +nx-X11-1.3.1-9 + +- Fixed Xserver/Imakefile which was still referencing NXpixmap.o. + +nx-X11-1.3.1-8 + +- Imported an updated fbgc.c from XFree86-4.3.99.902. This fixes + some minor problems reported by Valgrind. + +- A major problem was reported by Valgrind about reading after + the block allocated in fbCreatePixmap from AllocatePixmap. The + file pixmap.c has been modified so that 4 bytes are added to + the pixmap buffer at any new allocation. This quick hack should + solve the problem for both nxagent and the NXWin server. Further + investigation is planned for the next release. + +- Fixed Xtranssock.c to compile on Solaris where struct sigaction + doesn't have the sa_restorer member. + +nx-X11-1.3.1-5 + +- Renamed the NX-sun.def configuration file to NX-Sun.def. + +- Renamed the non-standard NX_iPAQ_XServer and NX_Zaurus_XServer + symbols to NXiPAQXServer and NXZaurusXServer. + +- Added the missing sun.cf.XF86.original file in config/cf. + +- Added the missing empty file host.def.XF86.original in the + same directory. + +- Added initialization of sa.sa_mask when setting sigaction() + for SIGCHLD. The problem was reported by Valgrind running + nxagent. + +- Removed an unused block of code from WaitFor.c. The code had + been commented out in previous versions. + +- Removed the non-standard colon at the end of version in this + CHANGELOG. + +- Removed the spurious spaces in this CHANGELOG. + +nx-X11-1.3.1-4 + +- Added a little workaround to the top Imakefile intended to + hide the makedepend warnings about non portable whitespaces + in sources. + +nx-X11-1.3.1-3 + +- Fixed compilation problem with nxagent-1.3.1-13. + +nx-X11-1.3.1-2 + +- Changes in NX-sun.def configuration file for Solaris to allow + compilation of the XKB extension. + +nx-X11-1.3.1-1 + +- Opened the 1.3.1 development branch. + +nx-X11-1.3.0-6 + +- Original output buffer size in stock XFree86 is 2048. We try + to reduce context switches and help stream compression by + increasing the maximum size of the buffer 8192. _NXFlushSize + determines when the display buffer is actually flushed. It is + set by default to 4096 but agents should set it to 0 if they + want to disable early flush. + +- Added the _NXLostSequenceFunction function pointer to let NX + agents suppress the error message and modify the default Xlib + behaviour when out-of-order sequence numbers are received. diff --git a/VERSION b/VERSION deleted file mode 120000 index 1da2874..0000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -VERSION.x2goagent \ No newline at end of file diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..a9f07dd --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +3.5.0.2 diff --git a/CHANGELOG.X.original b/WSDrawBuffer.h.X.original similarity index 100% copy from CHANGELOG.X.original copy to WSDrawBuffer.h.X.original diff --git a/debian/changelog b/debian/changelog index 2ccae7e..bf34ff8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,10 +1,20 @@ -x2goagent (3.5.0.2-0~x2go1) UNRELEASED; urgency=low +x2goagent (3.5.0.5-0~x2go1) UNRELEASED; urgency=low + [ Oleksandr Shneyder] + * New upstream version (3.5.0.5) - nx-X11-3.5.0-2 nxagent-3.5.0-5 nxauth-3.5.0-1 + * status + + -- Oleksandr Shneyder <oleksandr.shneyder@treuchtlingen.de> Tue, 04 Oct 2011 08:11:22 +0200 + +x2goagent (3.5.0.2-0~x2go1) unstable; urgency=low + + [ Mike Gabriel ] * New upstream version (3.5.0.2): - Patched in NX code from NX-X11-3.5.0-1 * Depend on NX libs >= 3.5.0. + * released - -- Mike Gabriel <mike.gabriel@das-netzwerkteam.de> Sun, 03 Jul 2011 16:57:57 +0200 + -- Oleksandr Shneyder <oleksandr.shneyder@treuchtlingen.de> Tue, 04 Oct 2011 08:11:03 +0200 x2goagent (3.4.0.5-0~x2go1) unstable; urgency=low diff --git a/debian/rules b/debian/rules old mode 100755 new mode 100644 diff --git a/debian/x2goagent.sh b/debian/x2goagent.sh old mode 100755 new mode 100644 diff --git a/lib/X11/XKBMAlloc.c b/lib/X11/XKBMAlloc.c index 91d87d5..d57d9a5 100644 --- a/lib/X11/XKBMAlloc.c +++ b/lib/X11/XKBMAlloc.c @@ -738,8 +738,13 @@ int tmp; _XkbFree(prev_key_sym_map); return BadAlloc; } +#ifdef NXAGENT_SERVER + bzero((char *)&xkb->map->key_sym_map[xkb->max_key_code+1], + tmp*sizeof(XkbSymMapRec)); +#else bzero((char *)&xkb->map->key_sym_map[xkb->max_key_code], tmp*sizeof(XkbSymMapRec)); +#endif if (changes) { changes->map.changed= _ExtendRange(changes->map.changed, XkbKeySymsMask,maxKC, @@ -756,7 +761,11 @@ int tmp; _XkbFree(prev_modmap); return BadAlloc; } +#ifdef NXAGENT_SERVER + bzero((char *)&xkb->map->modmap[xkb->max_key_code+1],tmp); +#else bzero((char *)&xkb->map->modmap[xkb->max_key_code],tmp); +#endif if (changes) { changes->map.changed= _ExtendRange(changes->map.changed, XkbModifierMapMask,maxKC, @@ -775,8 +784,13 @@ int tmp; _XkbFree(prev_behaviors); return BadAlloc; } +#ifdef NXAGENT_SERVER + bzero((char *)&xkb->server->behaviors[xkb->max_key_code+1], + tmp*sizeof(XkbBehavior)); +#else bzero((char *)&xkb->server->behaviors[xkb->max_key_code], tmp*sizeof(XkbBehavior)); +#endif if (changes) { changes->map.changed= _ExtendRange(changes->map.changed, XkbKeyBehaviorsMask,maxKC, @@ -793,8 +807,13 @@ int tmp; _XkbFree(prev_key_acts); return BadAlloc; } +#ifdef NXAGENT_SERVER + bzero((char *)&xkb->server->key_acts[xkb->max_key_code+1], + tmp*sizeof(unsigned short)); +#else bzero((char *)&xkb->server->key_acts[xkb->max_key_code], tmp*sizeof(unsigned short)); +#endif if (changes) { changes->map.changed= _ExtendRange(changes->map.changed, XkbKeyActionsMask,maxKC, @@ -811,8 +830,13 @@ int tmp; _XkbFree(prev_vmodmap); return BadAlloc; } +#ifdef NXAGENT_SERVER + bzero((char *)&xkb->server->vmodmap[xkb->max_key_code+1], + tmp*sizeof(unsigned short)); +#else bzero((char *)&xkb->server->vmodmap[xkb->max_key_code], tmp*sizeof(unsigned short)); +#endif if (changes) { changes->map.changed= _ExtendRange(changes->map.changed, XkbVirtualModMapMask,maxKC, @@ -830,8 +854,13 @@ int tmp; _XkbFree(prev_keys); return BadAlloc; } +#ifdef NXAGENT_SERVER + bzero((char *)&xkb->names->keys[xkb->max_key_code+1], + tmp*sizeof(XkbKeyNameRec)); +#else bzero((char *)&xkb->names->keys[xkb->max_key_code], tmp*sizeof(XkbKeyNameRec)); +#endif if (changes) { changes->names.changed= _ExtendRange(changes->names.changed, XkbKeyNamesMask,maxKC, diff --git a/lib/X11/XKBMAlloc.c.NX.original b/lib/X11/XKBMAlloc.c.NX.original new file mode 100644 index 0000000..d57d9a5 --- /dev/null +++ b/lib/X11/XKBMAlloc.c.NX.original @@ -0,0 +1,1023 @@ +/* $Xorg: XKBMAlloc.c,v 1.4 2000/08/17 19:45:02 cpqbld Exp $ */ +/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +Permission to use, copy, modify, and distribute this +software and its documentation for any purpose and without +fee is hereby granted, 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 Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS 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. + +********************************************************/ +/* $XFree86: xc/lib/X11/XKBMAlloc.c,v 3.11 2001/01/17 19:41:48 dawes Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#elif defined(HAVE_CONFIG_H) +#include <config.h> +#endif + +#ifndef XKB_IN_SERVER + +#include <stdio.h> +#define NEED_REPLIES +#define NEED_EVENTS +#include "Xlibint.h" +#include <X11/extensions/XKBproto.h> +#include <X11/keysym.h> +#include "XKBlibint.h" + +#else + +#include <stdio.h> +#include <X11/X.h> +#define NEED_EVENTS +#define NEED_REPLIES +#include <X11/Xproto.h> +#include "misc.h" +#include "inputstr.h" +#include <X11/keysym.h> +#define XKBSRV_NEED_FILE_FUNCS +#include <X11/extensions/XKBsrv.h> + +#endif /* XKB_IN_SERVER */ + +/***====================================================================***/ + +Status +XkbAllocClientMap(XkbDescPtr xkb,unsigned which,unsigned nTotalTypes) +{ +register int i; +XkbClientMapPtr map; + + if ((xkb==NULL)||((nTotalTypes>0)&&(nTotalTypes<XkbNumRequiredTypes))) + return BadValue; + if ((which&XkbKeySymsMask)&& + ((!XkbIsLegalKeycode(xkb->min_key_code))|| + (!XkbIsLegalKeycode(xkb->max_key_code))|| + (xkb->max_key_code<xkb->min_key_code))) { +#ifdef DEBUG +fprintf(stderr,"bad keycode (%d,%d) in XkbAllocClientMap\n", + xkb->min_key_code,xkb->max_key_code); +#endif + return BadValue; + } + + if (xkb->map==NULL) { + map= _XkbTypedCalloc(1,XkbClientMapRec); + if (map==NULL) + return BadAlloc; + xkb->map= map; + } + else map= xkb->map; + + if ((which&XkbKeyTypesMask)&&(nTotalTypes>0)) { + if (map->types==NULL) { + map->types= _XkbTypedCalloc(nTotalTypes,XkbKeyTypeRec); + if (map->types==NULL) + return BadAlloc; + map->num_types= 0; + map->size_types= nTotalTypes; + } + else if (map->size_types<nTotalTypes) { + XkbKeyTypeRec *prev_types = map->types; + + map->types= _XkbTypedRealloc(map->types,nTotalTypes,XkbKeyTypeRec); + if (map->types==NULL) { + _XkbFree(prev_types); + map->num_types= map->size_types= 0; + return BadAlloc; + } + map->size_types= nTotalTypes; + bzero(&map->types[map->num_types], + ((map->size_types-map->num_types)*sizeof(XkbKeyTypeRec))); + } + } + if (which&XkbKeySymsMask) { + int nKeys= XkbNumKeys(xkb); + if (map->syms==NULL) { + map->size_syms= (nKeys*15)/10; + map->syms= _XkbTypedCalloc(map->size_syms,KeySym); + if (!map->syms) { + map->size_syms= 0; + return BadAlloc; + } + map->num_syms= 1; + map->syms[0]= NoSymbol; + } + if (map->key_sym_map==NULL) { + i= xkb->max_key_code+1; + map->key_sym_map= _XkbTypedCalloc(i,XkbSymMapRec); + if (map->key_sym_map==NULL) + return BadAlloc; + } + } + if (which&XkbModifierMapMask) { + if ((!XkbIsLegalKeycode(xkb->min_key_code))|| + (!XkbIsLegalKeycode(xkb->max_key_code))|| + (xkb->max_key_code<xkb->min_key_code)) + return BadMatch; + if (map->modmap==NULL) { + i= xkb->max_key_code+1; + map->modmap= _XkbTypedCalloc(i,unsigned char); + if (map->modmap==NULL) + return BadAlloc; + } + } + return Success; +} + +Status +XkbAllocServerMap(XkbDescPtr xkb,unsigned which,unsigned nNewActions) +{ +register int i; +XkbServerMapPtr map; + + if (xkb==NULL) + return BadMatch; + if (xkb->server==NULL) { + map= _XkbTypedCalloc(1,XkbServerMapRec); + if (map==NULL) + return BadAlloc; + for (i=0;i<XkbNumVirtualMods;i++) { + map->vmods[i]= XkbNoModifierMask; + } + xkb->server= map; + } + else map= xkb->server; + if (which&XkbExplicitComponentsMask) { + if ((!XkbIsLegalKeycode(xkb->min_key_code))|| + (!XkbIsLegalKeycode(xkb->max_key_code))|| + (xkb->max_key_code<xkb->min_key_code)) + return BadMatch; + if (map->explicit==NULL) { + i= xkb->max_key_code+1; + map->explicit= _XkbTypedCalloc(i,unsigned char); + if (map->explicit==NULL) + return BadAlloc; + } + } + if (which&XkbKeyActionsMask) { + if ((!XkbIsLegalKeycode(xkb->min_key_code))|| + (!XkbIsLegalKeycode(xkb->max_key_code))|| + (xkb->max_key_code<xkb->min_key_code)) + return BadMatch; + if (nNewActions<1) + nNewActions= 1; + if (map->acts==NULL) { + map->acts= _XkbTypedCalloc((nNewActions+1),XkbAction); + if (map->acts==NULL) + return BadAlloc; + map->num_acts= 1; + map->size_acts= nNewActions+1; + } + else if ((map->size_acts-map->num_acts)<nNewActions) { + unsigned need; + XkbAction *prev_acts = map->acts; + need= map->num_acts+nNewActions; + map->acts= _XkbTypedRealloc(map->acts,need,XkbAction); + if (map->acts==NULL) { + _XkbFree(prev_acts); + map->num_acts= map->size_acts= 0; + return BadAlloc; + } + map->size_acts= need; + bzero(&map->acts[map->num_acts], + ((map->size_acts-map->num_acts)*sizeof(XkbAction))); + } + if (map->key_acts==NULL) { + i= xkb->max_key_code+1; + map->key_acts= _XkbTypedCalloc(i,unsigned short); + if (map->key_acts==NULL) + return BadAlloc; + } + } + if (which&XkbKeyBehaviorsMask) { + if ((!XkbIsLegalKeycode(xkb->min_key_code))|| + (!XkbIsLegalKeycode(xkb->max_key_code))|| + (xkb->max_key_code<xkb->min_key_code)) + return BadMatch; + if (map->behaviors==NULL) { + i= xkb->max_key_code+1; + map->behaviors= _XkbTypedCalloc(i,XkbBehavior); + if (map->behaviors==NULL) + return BadAlloc; + } + } + if (which&XkbVirtualModMapMask) { + if ((!XkbIsLegalKeycode(xkb->min_key_code))|| + (!XkbIsLegalKeycode(xkb->max_key_code))|| + (xkb->max_key_code<xkb->min_key_code)) + return BadMatch; + if (map->vmodmap==NULL) { + i= xkb->max_key_code+1; + map->vmodmap= _XkbTypedCalloc(i,unsigned short); + if (map->vmodmap==NULL) + return BadAlloc; + } + } + return Success; +} + +/***====================================================================***/ + +Status +XkbCopyKeyType(XkbKeyTypePtr from,XkbKeyTypePtr into) +{ + if ((!from)||(!into)) + return BadMatch; + if (into->map) { + _XkbFree(into->map); + into->map= NULL; + } + if (into->preserve) { + _XkbFree(into->preserve); + into->preserve= NULL; + } + if (into->level_names) { + _XkbFree(into->level_names); + into->level_names= NULL; + } + *into= *from; + if ((from->map)&&(into->map_count>0)) { + into->map= _XkbTypedCalloc(into->map_count,XkbKTMapEntryRec); + if (!into->map) + return BadAlloc; + memcpy(into->map,from->map,into->map_count*sizeof(XkbKTMapEntryRec)); + } + if ((from->preserve)&&(into->map_count>0)) { + into->preserve= _XkbTypedCalloc(into->map_count,XkbModsRec); + if (!into->preserve) + return BadAlloc; + memcpy(into->preserve,from->preserve, + into->map_count*sizeof(XkbModsRec)); + } + if ((from->level_names)&&(into->num_levels>0)) { + into->level_names= _XkbTypedCalloc(into->num_levels,Atom); + if (!into->level_names) + return BadAlloc; + memcpy(into->level_names,from->level_names, + into->num_levels*sizeof(Atom)); + } + return Success; +} + +Status +XkbCopyKeyTypes(XkbKeyTypePtr from,XkbKeyTypePtr into,int num_types) +{ +register int i,rtrn; + + if ((!from)||(!into)||(num_types<0)) + return BadMatch; + for (i=0;i<num_types;i++) { + if ((rtrn= XkbCopyKeyType(from++,into++))!=Success) + return rtrn; + } + return Success; +} + +XkbKeyTypePtr +XkbAddKeyType( XkbDescPtr xkb, + Atom name, + int map_count, + Bool want_preserve, + int num_lvls) +{ +register int i; +unsigned tmp; +XkbKeyTypePtr type; +XkbClientMapPtr map; + + if ((!xkb)||(num_lvls<1)) + return NULL; + map= xkb->map; + if ((map)&&(map->types)) { + for (i=0;i<map->num_types;i++) { + if (map->types[i].name==name) { + Status status; + status=XkbResizeKeyType(xkb,i,map_count,want_preserve,num_lvls); + return (status==Success?&map->types[i]:NULL); + } + } + } + if ((!map)||(!map->types)||(!map->num_types<XkbNumRequiredTypes)) { + tmp= XkbNumRequiredTypes+1; + if (XkbAllocClientMap(xkb,XkbKeyTypesMask,tmp)!=Success) + return NULL; + tmp= 0; + if (map->num_types<=XkbKeypadIndex) + tmp|= XkbKeypadMask; + if (map->num_types<=XkbAlphabeticIndex) + tmp|= XkbAlphabeticMask; + if (map->num_types<=XkbTwoLevelIndex) + tmp|= XkbTwoLevelMask; + if (map->num_types<=XkbOneLevelIndex) + tmp|= XkbOneLevelMask; + if (XkbInitCanonicalKeyTypes(xkb,tmp,XkbNoModifier)==Success) { + for (i=0;i<map->num_types;i++) { + Status status; + if (map->types[i].name!=name) + continue; + status=XkbResizeKeyType(xkb,i,map_count,want_preserve,num_lvls); + return (status==Success?&map->types[i]:NULL); + } + } + } + if ((map->num_types<=map->size_types)&& + (XkbAllocClientMap(xkb,XkbKeyTypesMask,map->num_types+1)!=Success)) { + return NULL; + } + type= &map->types[map->num_types]; + map->num_types++; + bzero((char *)type,sizeof(XkbKeyTypeRec)); + type->num_levels= num_lvls; + type->map_count= map_count; + type->name= name; + if (map_count>0) { + type->map= _XkbTypedCalloc(map_count,XkbKTMapEntryRec); + if (!type->map) { + map->num_types--; + return NULL; + } + if (want_preserve) { + type->preserve= _XkbTypedCalloc(map_count,XkbModsRec); + if (!type->preserve) { + _XkbFree(type->map); + map->num_types--; + return NULL; + } + } + } + return type; +} + +Status +XkbResizeKeyType( XkbDescPtr xkb, + int type_ndx, + int map_count, + Bool want_preserve, + int new_num_lvls) +{ +XkbKeyTypePtr type; +KeyCode matchingKeys[XkbMaxKeyCount],nMatchingKeys; + + if ((type_ndx<0)||(type_ndx>=xkb->map->num_types)||(map_count<0)|| + (new_num_lvls<1)) + return BadValue; + switch (type_ndx) { + case XkbOneLevelIndex: + if (new_num_lvls!=1) + return BadMatch; + break; + case XkbTwoLevelIndex: + case XkbAlphabeticIndex: + case XkbKeypadIndex: + if (new_num_lvls!=2) + return BadMatch; + break; + } + type= &xkb->map->types[type_ndx]; + if (map_count==0) { + if (type->map!=NULL) + _XkbFree(type->map); + type->map= NULL; + if (type->preserve!=NULL) + _XkbFree(type->preserve); + type->preserve= NULL; + type->map_count= 0; + } + else { + XkbKTMapEntryRec *prev_map = type->map; + + if ((map_count>type->map_count)||(type->map==NULL)) + type->map=_XkbTypedRealloc(type->map,map_count,XkbKTMapEntryRec); + if (!type->map) { + if (prev_map) + _XkbFree(prev_map); + return BadAlloc; + } + if (want_preserve) { + XkbModsRec *prev_preserve = type->preserve; + + if ((map_count>type->map_count)||(type->preserve==NULL)) { + type->preserve= _XkbTypedRealloc(type->preserve,map_count, + XkbModsRec); + } + if (!type->preserve) { + if (prev_preserve) + _XkbFree(prev_preserve); + return BadAlloc; + } + } + else if (type->preserve!=NULL) { + _XkbFree(type->preserve); + type->preserve= NULL; + } + type->map_count= map_count; + } + + if ((new_num_lvls>type->num_levels)||(type->level_names==NULL)) { + Atom * prev_level_names = type->level_names; + + type->level_names=_XkbTypedRealloc(type->level_names,new_num_lvls,Atom); + if (!type->level_names) { + if (prev_level_names) + _XkbFree(prev_level_names); + return BadAlloc; + } + } + /* + * Here's the theory: + * If the width of the type changed, we might have to resize the symbol + * maps for any keys that use the type for one or more groups. This is + * expensive, so we'll try to cull out any keys that are obviously okay: + * In any case: + * - keys that have a group width <= the old width are okay (because + * they could not possibly have been associated with the old type) + * If the key type increased in size: + * - keys that already have a group width >= to the new width are okay + * + keys that have a group width >= the old width but < the new width + * might have to be enlarged. + * If the key type decreased in size: + * - keys that have a group width > the old width don't have to be + * resized (because they must have some other wider type associated + * with some group). + * + keys that have a group width == the old width might have to be + * shrunk. + * The possibilities marked with '+' require us to examine the key types + * associated with each group for the key. + */ + bzero(matchingKeys,XkbMaxKeyCount*sizeof(KeyCode)); + nMatchingKeys= 0; + if (new_num_lvls>type->num_levels) { + int nTotal; + KeySym * newSyms; + int width,match,nResize; + register int i,g,nSyms; + + nResize= 0; + for (nTotal=1,i=xkb->min_key_code;i<=xkb->max_key_code;i++) { + width= XkbKeyGroupsWidth(xkb,i); + if (width<type->num_levels) + continue; + for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) { + if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) { + matchingKeys[nMatchingKeys++]= i; + match= 1; + } + } + if ((!match)||(width>=new_num_lvls)) + nTotal+= XkbKeyNumSyms(xkb,i); + else { + nTotal+= XkbKeyNumGroups(xkb,i)*new_num_lvls; + nResize++; + } + } + if (nResize>0) { + int nextMatch; + xkb->map->size_syms= (nTotal*12)/10; + newSyms = _XkbTypedCalloc(xkb->map->size_syms,KeySym); + if (newSyms==NULL) + return BadAlloc; + nextMatch= 0; + nSyms= 1; + for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { + if (matchingKeys[nextMatch]==i) { + KeySym *pOld; + nextMatch++; + width= XkbKeyGroupsWidth(xkb,i); + pOld= XkbKeySymsPtr(xkb,i); + for (g=XkbKeyNumGroups(xkb,i)-1;g>=0;g--) { + memcpy(&newSyms[nSyms+(new_num_lvls*g)],&pOld[width*g], + width*sizeof(KeySym)); + } + xkb->map->key_sym_map[i].offset= nSyms; + nSyms+= XkbKeyNumGroups(xkb,i)*new_num_lvls; + } + else { + memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i), + XkbKeyNumSyms(xkb,i)*sizeof(KeySym)); + xkb->map->key_sym_map[i].offset= nSyms; + nSyms+= XkbKeyNumSyms(xkb,i); + } + } + type->num_levels= new_num_lvls; + _XkbFree(xkb->map->syms); + xkb->map->syms= newSyms; + xkb->map->num_syms= nSyms; + return Success; + } + } + else if (new_num_lvls<type->num_levels) { + int width,match; + register int g,i; + for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { + width= XkbKeyGroupsWidth(xkb,i); + if (width<type->num_levels) + continue; + for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) { + if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) { + matchingKeys[nMatchingKeys++]= i; + match= 1; + } + } + } + } + if (nMatchingKeys>0) { + int key,firstClear; + register int i,g; + if (new_num_lvls>type->num_levels) + firstClear= type->num_levels; + else firstClear= new_num_lvls; + for (i=0;i<nMatchingKeys;i++) { + KeySym * pSyms; + int width,nClear; + + key= matchingKeys[i]; + width= XkbKeyGroupsWidth(xkb,key); + nClear= width-firstClear; + pSyms= XkbKeySymsPtr(xkb,key); + for (g=XkbKeyNumGroups(xkb,key)-1;g>=0;g--) { + if (XkbKeyKeyTypeIndex(xkb,key,g)==type_ndx) { + if (nClear>0) + bzero(&pSyms[g*width+firstClear],nClear*sizeof(KeySym)); + } + } + } + } + type->num_levels= new_num_lvls; + return Success; +} + +KeySym * +XkbResizeKeySyms(XkbDescPtr xkb,int key,int needed) +{ +register int i,nSyms,nKeySyms; +unsigned nOldSyms; +KeySym *newSyms; + + if (needed==0) { + xkb->map->key_sym_map[key].offset= 0; + return xkb->map->syms; + } + nOldSyms= XkbKeyNumSyms(xkb,key); + if (nOldSyms>=(unsigned)needed) { + return XkbKeySymsPtr(xkb,key); + } + if (xkb->map->size_syms-xkb->map->num_syms>=(unsigned)needed) { + if (nOldSyms>0) { + memcpy(&xkb->map->syms[xkb->map->num_syms],XkbKeySymsPtr(xkb,key), + nOldSyms*sizeof(KeySym)); + } + if ((needed-nOldSyms)>0) { + bzero(&xkb->map->syms[xkb->map->num_syms+XkbKeyNumSyms(xkb,key)], + (needed-nOldSyms)*sizeof(KeySym)); + } + xkb->map->key_sym_map[key].offset = xkb->map->num_syms; + xkb->map->num_syms+= needed; + return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; + } + xkb->map->size_syms+= (needed>32?needed:32); + newSyms = _XkbTypedCalloc(xkb->map->size_syms,KeySym); + if (newSyms==NULL) + return NULL; + newSyms[0]= NoSymbol; + nSyms = 1; + for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) { + int nCopy; + + nCopy= nKeySyms= XkbKeyNumSyms(xkb,i); + if ((nKeySyms==0)&&(i!=key)) + continue; + if (i==key) + nKeySyms= needed; + if (nCopy!=0) + memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i),nCopy*sizeof(KeySym)); + if (nKeySyms>nCopy) + bzero(&newSyms[nSyms+nCopy],(nKeySyms-nCopy)*sizeof(KeySym)); + xkb->map->key_sym_map[i].offset = nSyms; + nSyms+= nKeySyms; + } + _XkbFree(xkb->map->syms); + xkb->map->syms = newSyms; + xkb->map->num_syms = nSyms; + return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; +} + +static unsigned +_ExtendRange( unsigned int old_flags, + unsigned int flag, + KeyCode newKC, + KeyCode * old_min, + unsigned char * old_num) +{ + if ((old_flags&flag)==0) { + old_flags|= flag; + *old_min= newKC; + *old_num= 1; + } + else { + int last= (*old_min)+(*old_num)-1; + if (newKC<*old_min) { + *old_min= newKC; + *old_num= (last-newKC)+1; + } + else if (newKC>last) { + *old_num= (newKC-(*old_min))+1; + } + } + return old_flags; +} + +Status +XkbChangeKeycodeRange( XkbDescPtr xkb, + int minKC, + int maxKC, + XkbChangesPtr changes) +{ +int tmp; + + if ((!xkb)||(minKC<XkbMinLegalKeyCode)||(maxKC>XkbMaxLegalKeyCode)) + return BadValue; + if (minKC>maxKC) + return BadMatch; + if (minKC<xkb->min_key_code) { + if (changes) + changes->map.min_key_code= minKC; + tmp= xkb->min_key_code-minKC; + if (xkb->map) { + if (xkb->map->key_sym_map) { + bzero((char *)&xkb->map->key_sym_map[minKC], + tmp*sizeof(XkbSymMapRec)); + if (changes) { + changes->map.changed= _ExtendRange(changes->map.changed, + XkbKeySymsMask,minKC, + &changes->map.first_key_sym, + &changes->map.num_key_syms); + } + } + if (xkb->map->modmap) { + bzero((char *)&xkb->map->modmap[minKC],tmp); + if (changes) { + changes->map.changed= _ExtendRange(changes->map.changed, + XkbModifierMapMask,minKC, + &changes->map.first_modmap_key, + &changes->map.num_modmap_keys); + } + } + } + if (xkb->server) { + if (xkb->server->behaviors) { + bzero((char *)&xkb->server->behaviors[minKC], + tmp*sizeof(XkbBehavior)); + if (changes) { + changes->map.changed= _ExtendRange(changes->map.changed, + XkbKeyBehaviorsMask,minKC, + &changes->map.first_key_behavior, + &changes->map.num_key_behaviors); + } + } + if (xkb->server->key_acts) { + bzero((char *)&xkb->server->key_acts[minKC], + tmp*sizeof(unsigned short)); + if (changes) { + changes->map.changed= _ExtendRange(changes->map.changed, + XkbKeyActionsMask,minKC, + &changes->map.first_key_act, + &changes->map.num_key_acts); + } + } + if (xkb->server->vmodmap) { + bzero((char *)&xkb->server->vmodmap[minKC], + tmp*sizeof(unsigned short)); + if (changes) { + changes->map.changed= _ExtendRange(changes->map.changed, + XkbVirtualModMapMask,minKC, + &changes->map.first_modmap_key, + &changes->map.num_vmodmap_keys); + } + } + } + if ((xkb->names)&&(xkb->names->keys)) { + bzero((char *)&xkb->names->keys[minKC],tmp*sizeof(XkbKeyNameRec)); + if (changes) { + changes->names.changed= _ExtendRange(changes->names.changed, + XkbKeyNamesMask,minKC, + &changes->names.first_key, + &changes->names.num_keys); + } + } + xkb->min_key_code= minKC; + } + if (maxKC>xkb->max_key_code) { + if (changes) + changes->map.max_key_code= maxKC; + tmp= maxKC-xkb->max_key_code; + if (xkb->map) { + if (xkb->map->key_sym_map) { + XkbSymMapRec *prev_key_sym_map = xkb->map->key_sym_map; + + xkb->map->key_sym_map= _XkbTypedRealloc(xkb->map->key_sym_map, + (maxKC+1),XkbSymMapRec); + if (!xkb->map->key_sym_map) { + _XkbFree(prev_key_sym_map); + return BadAlloc; + } +#ifdef NXAGENT_SERVER + bzero((char *)&xkb->map->key_sym_map[xkb->max_key_code+1], + tmp*sizeof(XkbSymMapRec)); +#else + bzero((char *)&xkb->map->key_sym_map[xkb->max_key_code], + tmp*sizeof(XkbSymMapRec)); +#endif + if (changes) { + changes->map.changed= _ExtendRange(changes->map.changed, + XkbKeySymsMask,maxKC, + &changes->map.first_key_sym, + &changes->map.num_key_syms); + } + } + if (xkb->map->modmap) { + unsigned char *prev_modmap = xkb->map->modmap; + + xkb->map->modmap= _XkbTypedRealloc(xkb->map->modmap, + (maxKC+1),unsigned char); + if (!xkb->map->modmap) { + _XkbFree(prev_modmap); + return BadAlloc; + } +#ifdef NXAGENT_SERVER + bzero((char *)&xkb->map->modmap[xkb->max_key_code+1],tmp); +#else + bzero((char *)&xkb->map->modmap[xkb->max_key_code],tmp); +#endif + if (changes) { + changes->map.changed= _ExtendRange(changes->map.changed, + XkbModifierMapMask,maxKC, + &changes->map.first_modmap_key, + &changes->map.num_modmap_keys); + } + } + } + if (xkb->server) { + if (xkb->server->behaviors) { + XkbBehavior *prev_behaviors = xkb->server->behaviors; + + xkb->server->behaviors=_XkbTypedRealloc(xkb->server->behaviors, + (maxKC+1),XkbBehavior); + if (!xkb->server->behaviors) { + _XkbFree(prev_behaviors); + return BadAlloc; + } +#ifdef NXAGENT_SERVER + bzero((char *)&xkb->server->behaviors[xkb->max_key_code+1], + tmp*sizeof(XkbBehavior)); +#else + bzero((char *)&xkb->server->behaviors[xkb->max_key_code], + tmp*sizeof(XkbBehavior)); +#endif + if (changes) { + changes->map.changed= _ExtendRange(changes->map.changed, + XkbKeyBehaviorsMask,maxKC, + &changes->map.first_key_behavior, + &changes->map.num_key_behaviors); + } + } + if (xkb->server->key_acts) { + unsigned short *prev_key_acts = xkb->server->key_acts; + + xkb->server->key_acts= _XkbTypedRealloc(xkb->server->key_acts, + (maxKC+1),unsigned short); + if (!xkb->server->key_acts) { + _XkbFree(prev_key_acts); + return BadAlloc; + } +#ifdef NXAGENT_SERVER + bzero((char *)&xkb->server->key_acts[xkb->max_key_code+1], + tmp*sizeof(unsigned short)); +#else + bzero((char *)&xkb->server->key_acts[xkb->max_key_code], + tmp*sizeof(unsigned short)); +#endif + if (changes) { + changes->map.changed= _ExtendRange(changes->map.changed, + XkbKeyActionsMask,maxKC, + &changes->map.first_key_act, + &changes->map.num_key_acts); + } + } + if (xkb->server->vmodmap) { + unsigned short *prev_vmodmap = xkb->server->vmodmap; + + xkb->server->vmodmap= _XkbTypedRealloc(xkb->server->vmodmap, + (maxKC+1),unsigned short); + if (!xkb->server->vmodmap) { + _XkbFree(prev_vmodmap); + return BadAlloc; + } +#ifdef NXAGENT_SERVER + bzero((char *)&xkb->server->vmodmap[xkb->max_key_code+1], + tmp*sizeof(unsigned short)); +#else + bzero((char *)&xkb->server->vmodmap[xkb->max_key_code], + tmp*sizeof(unsigned short)); +#endif + if (changes) { + changes->map.changed= _ExtendRange(changes->map.changed, + XkbVirtualModMapMask,maxKC, + &changes->map.first_modmap_key, + &changes->map.num_vmodmap_keys); + } + } + } + if ((xkb->names)&&(xkb->names->keys)) { + XkbKeyNameRec *prev_keys = xkb->names->keys; + + xkb->names->keys= _XkbTypedRealloc(xkb->names->keys, + (maxKC+1),XkbKeyNameRec); + if (!xkb->names->keys) { + _XkbFree(prev_keys); + return BadAlloc; + } +#ifdef NXAGENT_SERVER + bzero((char *)&xkb->names->keys[xkb->max_key_code+1], + tmp*sizeof(XkbKeyNameRec)); +#else + bzero((char *)&xkb->names->keys[xkb->max_key_code], + tmp*sizeof(XkbKeyNameRec)); +#endif + if (changes) { + changes->names.changed= _ExtendRange(changes->names.changed, + XkbKeyNamesMask,maxKC, + &changes->names.first_key, + &changes->names.num_keys); + } + } + xkb->max_key_code= maxKC; + } + return Success; +} + +XkbAction * +XkbResizeKeyActions(XkbDescPtr xkb,int key,int needed) +{ +register int i,nActs; +XkbAction *newActs; + + if (needed==0) { + xkb->server->key_acts[key]= 0; + return NULL; + } + if (XkbKeyHasActions(xkb,key)&&(XkbKeyNumSyms(xkb,key)>=(unsigned)needed)) + return XkbKeyActionsPtr(xkb,key); + if (xkb->server->size_acts-xkb->server->num_acts>=(unsigned)needed) { + xkb->server->key_acts[key]= xkb->server->num_acts; + xkb->server->num_acts+= needed; + return &xkb->server->acts[xkb->server->key_acts[key]]; + } + xkb->server->size_acts= xkb->server->num_acts+needed+8; + newActs = _XkbTypedCalloc(xkb->server->size_acts,XkbAction); + if (newActs==NULL) + return NULL; + newActs[0].type = XkbSA_NoAction; + nActs = 1; + for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) { + int nKeyActs,nCopy; + + if ((xkb->server->key_acts[i]==0)&&(i!=key)) + continue; + + nCopy= nKeyActs= XkbKeyNumActions(xkb,i); + if (i==key) { + nKeyActs= needed; + if (needed<nCopy) + nCopy= needed; + } + + if (nCopy>0) + memcpy(&newActs[nActs],XkbKeyActionsPtr(xkb,i), + nCopy*sizeof(XkbAction)); + if (nCopy<nKeyActs) + bzero(&newActs[nActs+nCopy],(nKeyActs-nCopy)*sizeof(XkbAction)); + xkb->server->key_acts[i]= nActs; + nActs+= nKeyActs; + } + _XkbFree(xkb->server->acts); + xkb->server->acts = newActs; + xkb->server->num_acts= nActs; + return &xkb->server->acts[xkb->server->key_acts[key]]; +} + +void +XkbFreeClientMap(XkbDescPtr xkb,unsigned what,Bool freeMap) +{ +XkbClientMapPtr map; + + if ((xkb==NULL)||(xkb->map==NULL)) + return; + if (freeMap) + what= XkbAllClientInfoMask; + map= xkb->map; + if (what&XkbKeyTypesMask) { + if (map->types!=NULL) { + if (map->num_types>0) { + register int i; + XkbKeyTypePtr type; + for (i=0,type=map->types;i<map->num_types;i++,type++) { + if (type->map!=NULL) { + _XkbFree(type->map); + type->map= NULL; + } + if (type->preserve!=NULL) { + _XkbFree(type->preserve); + type->preserve= NULL; + } + type->map_count= 0; + if (type->level_names!=NULL) { + _XkbFree(type->level_names); + type->level_names= NULL; + } + } + } + _XkbFree(map->types); + map->num_types= map->size_types= 0; + map->types= NULL; + } + } + if (what&XkbKeySymsMask) { + if (map->key_sym_map!=NULL) { + _XkbFree(map->key_sym_map); + map->key_sym_map= NULL; + } + if (map->syms!=NULL) { + _XkbFree(map->syms); + map->size_syms= map->num_syms= 0; + map->syms= NULL; + } + } + if ((what&XkbModifierMapMask)&&(map->modmap!=NULL)) { + _XkbFree(map->modmap); + map->modmap= NULL; + } + if (freeMap) { + _XkbFree(xkb->map); + xkb->map= NULL; + } + return; +} + +void +XkbFreeServerMap(XkbDescPtr xkb,unsigned what,Bool freeMap) +{ +XkbServerMapPtr map; + + if ((xkb==NULL)||(xkb->server==NULL)) + return; + if (freeMap) + what= XkbAllServerInfoMask; + map= xkb->server; + if ((what&XkbExplicitComponentsMask)&&(map->explicit!=NULL)) { + _XkbFree(map->explicit); + map->explicit= NULL; + } + if (what&XkbKeyActionsMask) { + if (map->key_acts!=NULL) { + _XkbFree(map->key_acts); + map->key_acts= NULL; + } + if (map->acts!=NULL) { + _XkbFree(map->acts); + map->num_acts= map->size_acts= 0; + map->acts= NULL; + } + } + if ((what&XkbKeyBehaviorsMask)&&(map->behaviors!=NULL)) { + _XkbFree(map->behaviors); + map->behaviors= NULL; + } + if ((what&XkbVirtualModMapMask)&&(map->vmodmap!=NULL)) { + _XkbFree(map->vmodmap); + map->vmodmap= NULL; + } + + if (freeMap) { + _XkbFree(xkb->server); + xkb->server= NULL; + } + return; +} diff --git a/lib/X11/XKBMAlloc.c b/lib/X11/XKBMAlloc.c.X.original similarity index 100% copy from lib/X11/XKBMAlloc.c copy to lib/X11/XKBMAlloc.c.X.original diff --git a/programs/Xserver/hw/nxagent/Args.c b/programs/Xserver/hw/nxagent/Args.c index 8fbb275..ecf0a21 100644 --- a/programs/Xserver/hw/nxagent/Args.c +++ b/programs/Xserver/hw/nxagent/Args.c @@ -135,6 +135,8 @@ char *nxagentKeyboard = NULL; Bool nxagentOnce = True; +int nxagentRemoteMajor = -1; + static void nxagentParseOptionString(char*); /* @@ -1578,6 +1580,8 @@ N/A nxagentAlphaCompat = 0; } + nxagentRemoteMajor = remoteMajor; + if (nxagentPackMethod == -1) { nxagentPackMethod = packMethod; diff --git a/programs/Xserver/hw/nxagent/Args.h b/programs/Xserver/hw/nxagent/Args.h index 9cb97ca..8f4d05d 100644 --- a/programs/Xserver/hw/nxagent/Args.h +++ b/programs/Xserver/hw/nxagent/Args.h @@ -81,4 +81,6 @@ void nxagentSetCoalescence(void); extern int nxagentUserDefinedFontPath; +extern int nxagentRemoteMajor; + #endif /* __Args_H__ */ diff --git a/programs/Xserver/hw/nxagent/CHANGELOG b/programs/Xserver/hw/nxagent/CHANGELOG index fc6f2a8..15bd97a 100644 --- a/programs/Xserver/hw/nxagent/CHANGELOG +++ b/programs/Xserver/hw/nxagent/CHANGELOG @@ -1,5 +1,24 @@ ChangeLog: +nxagent-3.5.0-5 + +- The NX agent failed to resize its own window to fit the desktop size + in shadow sessions. TR07I02561 is now fixed also in shadow mode. + +nxagent-3.5.0-4 + +- Fixed TR07I02530. Solved a buffer overflow occurring when the '-fp' + option value exceeds 1024 characters. + +- Extended list of the available screen geometries. + +nxagent-3.5.0-3 + +- Fixed TR08I02572. Upgraded RandR extension to version 1.2. + +- Fixed TR07I02561. The NX agent failed to resize its own window to + fit the desktop size. + x2goagent-3.5.0.2 - forked nxagent-3.5.0-1 diff --git a/programs/Xserver/hw/nxagent/CHANGELOG.orig b/programs/Xserver/hw/nxagent/CHANGELOG.orig new file mode 100644 index 0000000..0f20b79 --- /dev/null +++ b/programs/Xserver/hw/nxagent/CHANGELOG.orig @@ -0,0 +1,6326 @@ +ChangeLog: + +nxagent-3.5.0-5 + +- The NX agent failed to resize its own window to fit the desktop size + in shadow sessions. TR07I02561 is now fixed also in shadow mode. + +nxagent-3.5.0-4 + +- Fixed TR07I02530. Solved a buffer overflow occurring when the '-fp' + option value exceeds 1024 characters. + +- Extended list of the available screen geometries. + +nxagent-3.5.0-3 + +- Fixed TR08I02572. Upgraded RandR extension to version 1.2. + +- Fixed TR07I02561. The NX agent failed to resize its own window to + fit the desktop size. + +nxagent-3.5.0-2 + +- Fixed TR0502449. Initialized font server path even if font server + connection fails. + +nxagent-3.5.0-1 + +- Opened the 3.5.0 branch based on nxagent-3.4.0-16. + +- Updated copyright to year 2009. + +- Fixed TR0302438. Added a check in function exporting property in + order to handle the case looking up an atom name returns a null + pointer. + +nxagent-3.4.0-16 + +- Updated copyright to year 2011. + +nxagent-3.4.0-15 + +- Added reference to fixed TR11H02405. + +nxagent-3.4.0-14 + +- Reverted fix for TR03H02335 implemented in nxagent-3.4.0-6. The + emulation of right click by Control key + left click introduces + issues for some applications changing the reaction to the left click + depending on the state of Control key. Issue reported in TR03H02335 + affects Apple laptop touchpads having a single button acting as + left button: on those devices the right button can be emulated by + a double-fingered tap (using two fingertips simultaneously). + +nxagent-3.4.0-13 + +- Fixed TR12H02414. Exported property must be split if ChangeProperty + request exceeds 262140 bytes. + +- Reset AllScreens option at reconnection time if full screen mode + have to be automatically turned off. + +nxagent-3.4.0-12 + +- If one of the two full screen modes is active ('one screen' or 'all + screens') both keystrokes Ctrl-Alt-F and Ctrl-Alt-Shift-F change the + mode back to 'windowed'. + +- Fixed TR11H02405. XRenderFreePicture is called only for pictures + that were actually created on the X server side. + +- Ctrl+Alt+f switch fullscreen to all monitors, while Ctrl+Alt+Shift+f + does it to one monitor only. + +- If the fullscreen option is enabled at the startup, session starts + in the fullscreen mode on all monitors. + +- Added a call to XReparentWindow in the nxagentSwitchAllScreens(). + +- Corrected focus and grab when switching to fullscreen on + all monitors. + +- Removed a compile warning e deleted some unused variables. + +- Removed nxagentPointerAndKeyboardGrabbed variable. + +- Use the override redirect attribute to switch to fullscreen to all + monitors instead of send _NET_WM_FULLSCREEN_MONITORS hint to the WM. + +- Added nxagentMinimizeFromFullScreen(), nxagentMaximizeToFullScreen() + and nxagentCreateIconWindow(). + +- Removed check on EnterNotify to grab the keyboard in fullscreen + mode not only if mode is 'NotifyNormal'. + +nxagent-3.4.0-11 + +- Corrected switching between viewport mode and resize mode. + +- Fixed TR04H02340. Keycode is correctly translated in shadow sessions + also if the remote X display is using evdev. + +nxagent-3.4.0-10 + +- Handled XGrabKeyboard() return value. + +- Fixed TR10D01512. NumLock and CapsLock keys are now synchronized + between local and remote. + +nxagent-3.4.0-9 + +- Fixed TR06H02362. No icon was swown in the task bar. + +- Fixed keyboard grab in fullscreen mode. + +- Fixed compiler warnings. + +nxagent-3.4.0-8 + +- Grab the keyboard in fullscreen mode on EnterNotify only if mode is + 'NotifyNormal'. + +- Yield control in the dispatch loop in case we stop the smart sche- + duler timer while waiting for a reply from the remote display. + +nxagent-3.4.0-7 + +- Fixed TR08D01478. The communication with the compiz window manager + by means of the _NET_WM_PING property was not handled properly. + +- Fixed a type mismatch in XKB events on 64 bit platforms. + +- Moved grab/ungrab keyboard from focus in/out event to enter/leave + notify event. + +- Removed nxagentIconWindow because it's not longer used. + +nxagent-3.4.0-6 + +- Fixed TR09F02102. Problem was with pointer buttons map. + +- Fixed TR02H02327. Some KeyRelease events was discarded. + +- Fixed up Num and Caps locks. + +- Fixed TR03H02335. Emulated right mouse button for Mac clients. + +- Added utilities to print info about internal and remote windows. + +- Fixed TR01F01995. Solved a picture resource leak by destroying remo- + te pictures only when their reference counter returns to zero. + +- Fixed TR04H02337. Errors occurred because pictures with no drawable + were handled badly. + +- Implemented handling nxagent's private for gradient pictures and so- + lid fill picture. + +- Fixed BadMatch condition check in function ProcRenderComposite. + +- Fixed nxagentComposite() to handle situations with source picture + drawable pointing to NULL. + +- Implemented render acceleration for requests: CreateSolidFill, + CreateLinearGradient, CreateRadialGradient, CreateConicalGradient. + +- Fixed TR03G02196. Dialogs are shown to the fore when the NX session + is in fullscreen mode. + +- Changed mechanism to switch to fullscreen mode. Now the override + redirect attribute is no longer used and _NET_WM_STATE_FULLSCREEN + hint is sent to the WM. + +nxagent-3.4.0-5 + +- Updated copyright to year 2010. + +nxagent-3.4.0-4 + +- Fixed TR07F02090. Now XDMCP sessions start without problems. + +- Fixed TR08G02259. Corrected window border granularity of rootless + session at reconnection on 64 bit platforms. + +- Fixed TR11G02290. Forcing null timeout with queued events only if + display connection is up. This prevents the flood of session log. + +- Fixed TR10G02287. Now QueryTree's loop is aborted in case of failure + and session log isn't filled anymore with repeated warning messages. + +- Fixed TR01G02154. Corrected window placement when switching between + fullscreen and windowed mode. + +- Fixed TR09G02276. Now the agent does not receive unwanted characters + while interacting with the local window manager. + +- Implemented FR02G02174. Added ability to do large screen pans in + viewport mode through key combination Ctrl+Alt+Shift+Arrow. + +- Corrected parsing of the 'client' option when the client OS is Mac. + +nxagent-3.4.0-3 + +- Fixed TR09G02271. The array containing the font name fields was not + correctly initialized for non-standard font names. + +nxagent-3.4.0-2 + +- Updated copyright to year 2009. + +nxagent-3.4.0-1 + +- Opened the 3.4.0 branch based on nxagent-3.3.0-19. + +- Changed the printed version number. + +nxagent-3.3.0-19 + +- Fixed TR09G02266. A proper error message is printed in the session + log if the shadowing initialization fails because of a mismatch in + the visual class. + +- Added a workaround for X servers that doesn't return 1 among the + available depths. + +nxagent-3.3.0-18 + +- The area to restore from the backing store is limited by the screen + size instead of the visible screen. + +nxagent-3.3.0-17 + +- Fixed TR12F02150. The agent could crash when copying text from VNC + viewer. Fixed by aborting the procedure in case the retrieved pro- + perty has not a valid format. + +nxagent-3.3.0-16 + +- Fixed TR07G02247. Don't try to call XSetWindowColormap() if the + window has no colormap, e.g. if its class is InputOnly. + +nxagent-3.3.0-15 + +- Fixed TR04G02210. Region is cut to the visible screen before re- + storing areas from the backing store. + +- Fixed TR07G02246. Box is shrinked if bounds can't stay in a short + signed integer. + +nxagent-3.3.0-14 + +- Fixed TR03G02206. waitpid() call was missing for the "Fonts replace- + ment" dialog type. + +- Fixed TR03G02195. Added a properties structure compatible with 32 + and 64 bit platform types. + +nxagent-3.3.0-13 + +- Handle the window unmap immediately. Don't add it to the configure + queue. + +nxagent-3.3.0-12 + +- Fixed TR03G02200. Timestamps could be in the future in KeyRelease + events sent to the X clients. + +- Added debug logging of input devices state Logging can be enabled + or disabled via the Ctrl+Alt+x shortcut. State info is dumped every + 5 seconds. + +- Added Ctrl+Alt+y shortcut used to deactivate input devices grab for + debug purposes. + +nxagent-3.3.0-11 + +- Changed the message logging the screen size changes, in order to + show the fullscreen state. + +- Handle the window unmapping in the nxagentConfigureWindow queue. + +nxagent-3.3.0-10 + +- Fixed TR12F02146. Compare the drawable and the bitmap data before + realizing the image update, in order to delay the data clean up that + caused the memcmp() failure. + +- Fixed TR01G02156. Reduce the exposing area by subtracting the ex- + posed region. + +- Fixed a compile warning in Drawable.c. + +- Added detailed logs in the nxagentSynchronizeRegion() function if + the data memory allocation fails. + +nxagent-3.3.0-9 + +- Added /usr/NX/share/base to alternate font paths. This would fix + TR11F02130 if fonts fixed and cursor are installed there. + +- Changed Keyboard initialization and reset. This change should fix + TR11F02129, TR11F02131, TR11F02132. + +nxagent-3.3.0-8 + +- Fixed TR12F02144. Image bits of render glyphs are copied before they + are cleaned. This will avoid a memory corruption. + +- Fixed TR12F02145. When dispatching a MotionNotify event, check if a + top-level window has been entered before trying to show the pulldown + dialog. + +nxagent-3.3.0-7 + +- Added debug code for pointer input. + +nxagent-3.3.0-6 + +- Fixed compile warnings. + +nxagent-3.3.0-5 + +- Disabled verbose logging in Rootless.c. + +nxagent-3.3.0-4 + +- Fix the XKB map load in the case of 64 bit server. + +nxagent-3.3.0-3 + +- Fixed TR10F02119. If the remote X display is using evdev keyboard + then copy maps from remote. + +- Upgraded VERSION to 3.3.0. + +nxagent-3.3.0-2 + +- Fixed TR10F02115. Painting errors occurred when screen areas beyond + the current viewport became viewable in the NX Client for Windows. + +- Using a new struct type nxagentWMHints to avoid type mismatch on + 64 bit platforms. + +- Added debug utilities for pointer input. + +nxagent-3.3.0-1 + +- Opened the 3.3.0 branch based on nxagent-3.2.0-12. + +nxagent-3.2.0-12 + +- Ignore 'resize' option at reconnection if viewport mode is on. + +- Fixed TR08E01814. Added shadow keymap initialization in order to + enable nxcompshad to translate keycodes across different layouts. + +nxagent-3.2.0-11 + +- Fixed TR08F02098. Function splitting font names has to be instruct- + ed to handle the right number of fields. + +nxagent-3.2.0-10 + +- Extended fix for TR07F02091 to include font names having zero in + fields RESOLUTION_X and RESOLUTION_Y. + +nxagent-3.2.0-9 + +- Fixed TR07F02091. Scalable fonts were not correctly listed among + available fonts. + +- Fixed TR06F02080. Use the corrupted area extents as maximum size of + the image data. + +nxagent-3.2.0-8 + +- Fixed TR07F02082. The agent server could be unable to init core + keyboard on 64 bit systems. + +nxagent-3.2.0-7 + +- Imported patch fixing issues from X.Org security advisory, June + 11th, 2008: Multiple vulnerabilities in X server extensions. CVE + IDs: CVE-2008-1377, CVE-2008-1379, CVE-2008-2360, CVE-2008-2361, + CVE-2008-2362. + +nxagent-3.2.0-6 + +- Fixed TR05F02063. Ignore ReparentNotify events for non-rootless + sessions. + +- Fixed TR06F02068. Try to pack images only if format is ZPixmap. + +- Don't require reparent on close of NX window. + +nxagent-3.2.0-5 + +- Fixed TR04F02044. Restored the original MakeRootTile() function in + order to create the root window background pixmap. + +- Fixed TR04F02041. Gnome panels stayed on top of the NX session win- + dow with desktops running Compiz. This fix provides a solution for + the Fullscreen mode. + +- Improved for the shadow session the handling of master session win- + dow resize. + +nxagent-3.2.0-4 + +- Fixed TR10D01535. The agent window is not minimized anymore when + pointer leaves. + +- Changes aimed to avoid possible type mismatch in XDisplay struct + on 64 bit architectures. + +nxagent-3.2.0-3 + +- Fixed a build issue on Solaris. + +nxagent-3.2.0-2 + +- Code clean up. Moved a variable definition to the beginnning of a + block. + +nxagent-3.2.0-1 + +- Opened the 3.2.0 branch based on nxagent-3.1.0-9. + +nxagent-3.1.0-9 + +- Fixed TR03F02025. German umlauts couldn't be pasted into a remote + Windows application. Now also the UTF8_STRING target is available + for ConvertSelection requests. + +- Fixed TR03F02031. Moved SetScreenSaverTimer() call in order to avoid + undesired reset of the auto-disconnect timeout when a screen saver + turns on. + +nxagent-3.1.0-8 + +- Added reference to fixed TR02F02007 and TR07E01762 in the CHANGELOG. + +- Set the GC trap before calling fbPolySegment. + +- Fixed TR09E01863. A flag is set if a resource has been added or fre- + ed and it is checked in FindClientResourcesByType(). + +- Added void entries to nxagentRequestLiteral vector in order to avoid + a wrong string is printed to the output for NoOperation request. + +- Fixed TR11E01948. Now keyboard status is initialized again after + the NX session is reconnected. This avoids CAPS LOCK and NUM LOCK + synchronization problems. + +- Added nxagentXkbCapsTrap and nxagentXkbNumTrap to avoid CAPS LOCK + and NUM LOCK synchronization problems when CAPS LOCK or NUM LOCK is + the first key to be pressed in the NX session. + +- Corrected subSize variable initialization in nxagentRealizeImage(). + +- Fixed various memory leaks. + +- Fixed TR11E01950. Copy and paste via edit menu didn't work for some + applications. + +- Corrected property type in nxagentRequestSelection(). Some external + applications didn't enable their paste button when nxagent was the + owner of the CLIPBOARD selection. + +- Added struct to save values queried by XQueryExtension for XFixes + extension. + +nxagent-3.1.0-7 + +- Imported patch fixing issues from X.Org security advisory, January + 17th, 2008: Multiple vulnerabilities in the X server. CVE IDs: + CVE-2007-5760 CVE-2007-5958 CVE-2007-6427 CVE-2007-6428 + CVE-2007-6429 CVE-2008-0006. + +- Fixed TR02F02007. Handled the case if nxagentCreateDrawableBitmap() + fails to create the pixmap intended to store the bitmap data. + +nxagent-3.1.0-6 + +- Fixed a compile warning in Args.c. + +- The synchronization loop breaks if the drawable is clean when it's + not supposed to be. + +- Fixed TR12E01966. Emacs tooltips were not displayed properly. Added + a check on the event mask before calling miWindowExposures(). + +- Fixed TR01F01982. ConfigureNotify warning is printed in verbose mode + only. + +nxagent-3.1.0-5 + +- Moved some variable definitions placed in ProcGetProperty(). + +nxagent-3.1.0-4 + +- Fixed TR06D01397. The problem was: drag & drop operations between + windows of Java applications didn't work in NX Client for Windows. + +- Implemented FR12E01957. Added a limit to the amount of data that can + be pasted from an NX session into an external application. The new + option - named 'copysize' - can be read from the 'options' file. + +nxagent-3.1.0-3 + +- Fixed TR12E01963. The window tree is revalidated explicitly after + recomputing the root window clip regions. + +nxagent-3.1.0-2 + +- Fixed TR11E01946. Forcing exposures on regions saved in the backing + store could bring to unexpected results. + +- Fixed TR11E01928. Animated cursors were not properly disconnected + and reconnected. + +nxagent-3.1.0-1 + +- Opened the 3.1.0 branch based on nxagent-3.0.0-93. + +nxagent-3.0.0-93 + +- Fixed TR10E01913. Now bell settings are restored after the agent + reconnects. + +nxagent-3.0.0-92 + +- Fixed a compilation error on 64 bit platforms. + +nxagent-3.0.0-91 + +- Checked the window synchronization status before subtracting an ex- + posed area from the corrupted region. + +nxagent-3.0.0-90 + +- Fixed TR11E01932. In case of rootless session displayed by NXWin X + server, synthetic ConfigureNotify events are generated by the X11 + agent. This helps to correct menu navigation in Java 1.6.0. + +- Fixed the handling of 'client' parameter. + +- Fixed bad refreshes in viewport navigation in the case of Windows + client. + +- Fixed TR11E01930. If the defer level is set by means of the command + line, the DeferLevel option is not reset while resuming the session. + +- Fixed TR07E01762. Problem in comparison of font names. + +- Printed the new geometry in the session log when the agent screen is + resized. + +nxagent-3.0.0-89 + +- Fixed TR10E01919. The agent could crash in the routine in charge of + find a replacement for a missing font. + +- Removed an unuseful log message. + +nxagent-3.0.0-88 + +- Fixed TR10D01539. Some XKEYBOARD requests are disabled if the option + 'keyboard' has value 'query'. This locks the initial keyboard map. + Enabling/disabling of XKEYBOARD requests is done at run time. + +- Added -noxkblock command line option enabling the XKEYBOARD requests + even if the option 'keyboard' value is 'query'. + +nxagent-3.0.0-87 + +- Reworked the handling of CT_PIXMAP client clips. Clips are always + converted in regions for internal use, while bitmap are saved for + operations involving the remote X. + +nxagent-3.0.0-86 + +- Fixed TR07E01749. Now using different resolution between shadow + and master session with shadow display option 'As on the server' + doesn't display black borders. + +- Fixed TR09E01852. The GC clips of type CT_PIXMAP are not converted + in regions. This avoids generating regions made up by thousands of + rectangles. Backing store function SetClipmaskRgn is implemented by + a stub doing nothing. + +nxagent-3.0.0-85 + +- Fixed TR08E01841. Exposed are forced to new areas exposed by the + viewport. + +- Fixed TR02E01645. Remote exposures was blocked if the NX client was + running on Linux without window manager. + +- Even if the agent window is fully obscured, synchronization is not + skipped if the Composite extension of the remote display is in use. + +- Fixed TR08E01851. Exposures events have to be internally generated + for regions that can't be restored because the backing pixmap is + corrupted. + +- Fixed TR08E01847. The initial values of store used to save XChangeGC + calls are set to the default GC values. + +- When a drawable becomes synchronized, its outdated bitmap is destro- + yed. + +- If a pixmap is not fully synchronized after a synchronization loop + it is cleared, just like windows. + +- Solved a problem causing some pixmaps to remain among the corrup- + ted resources even if they were synchronized. + +nxagent-3.0.0-84 + +- Renamed Misc.h as Utils.h to solve name clashes on Windows platform. + +nxagent-3.0.0-83 + +- Changes to include correctly declaration of _XDisplay structure on + 64 bit platforms. Further tests are needed to confirm that it fixes + TR08E01824. + +nxagent-3.0.0-82 + +- Fixed TR08E01821. Changed nxagentAddItemBSPixmapList() to check if + the pixmap item has already an entry in the list before adding it. + +- Fixed TR07E01795. Sun Studio main window showed only its grey back- + ground. Changed clipboard events handling to let the agent notify + a failure in converting selection. + +nxagent-3.0.0-81 + +- Based on nxagent-3.0.0-78. + +- The agent options are saved before reopening the display in the + reconnection procedure. If the new initialization fails the backup + values of options are restored. + +- Keyboard device info are saved before the keyboard reset occuring + in the reconnection procedure. If the new initialization of the + keyboard fails, the old values are restored. + +- The initialization procedure of keyboard device returns with error + if it fails to retrieve the keyboard mapping information from the + remote display. + +- The reconnection fails if the default depth of the new display is + different from the previous one. + +- The session can be migrated if the visuals don't match for color + masks swapping. At the moment there are no conversions to line up + the RGB masks, so even if the session can be migrated, incorrect + colors may be shown. + +nxagent-3.0.0-80 + +- The agent options are saved before reopening the display in the + reconnection procedure. If the new initialization fails the backup + values of options are restored. + +- The flag storing that a SIGHUP has been received is reset if the + function reconnecting the session fails. + +nxagent-3.0.0-79 + +- Changed the SIGHUP handler not to ignore the signal if the state + is SESSION_GOING_UP or SESSION_GOING_DOWN. + +- Keyboard device info are saved before the keybord reset occuring + in the reconnection procedure. If the new initialization of the + keyboard fails, the old values are restored. + +- The initialization procedure of keyboard device returns with error + if it fails to retrieve the keyboard mapping information from the + remote display. + +- The reconnection fails if the default depth of the new display is + different from the previous one. + +- The session can be migrated if the visuals don't match for color + masks swapping. At the moment there are no conversions to line up + the RGB masks, so even if the session can be migrated, incorrect + colors may be shown. + +nxagent-3.0.0-78 + +- Fixed TR07E01747. Fixed warnings occuring when compiling for AMD64. + +- Fixed TR07E01753. NoMachine WM icon in the title bar is displayed + correctly. + +- Fixed TR03E01656. If client and server endianess didn't match, glyph + images bits have to be only temporarily swapped. + +- Fixed TR07E01746. Terminate the shadow agent if the option 'shadow' + is empty. + +- Added option '-verbose'. It enables the printing of errors received + by the agent from the remote X server. + +- Warnings related to missing fonts are printed only if verbose mode + is enabled. + +- Disabled a log message related to the use of Composite extension. + +nxagent-3.0.0-77 + +- The pixmap formats are initialized without taking care of which are + supported on the remote display. + +- Removed the check for pixmap format compatibility when migrating the + session to a new display. + +- Fixed TR06E01725. A minimum set of available picture formats is + used to ensure a wide migration from/to different displays. + +- The PictFormat structures used by nxagent are no longer filtered + with the ones available on the real display. + +- The background pixmaps are cleared while reconnecting in order to + make them usable. + +- Fixed TR01E01619. Changed the RandR implementation to return a re- + fresh rate other than zero. + +nxagent-3.0.0-76 + +- Changed the keystroke to force the drawable's synchronization to + CTRL-ALT-J. + +nxagent-3.0.0-75 + +- If the backing store tries to restore areas from a corrupted pixmap, + such areas are subtracted from the saved region, so that exposures + will be sent for them. + +nxagent-3.0.0-74 + +- Don't skip the synchronization when there are more clients ready. + This temporarily solves the synchronization problems observed in + the previous versions if one or more clients kept the agent busy. + +nxagent-3.0.0-73 + +- If the PolyFillRect() uses a FillStippled or a FillOpaqueStippled + fill style and the destination is corrupted, the area affected by + the operation is first synchronized. + +nxagent-3.0.0-72 + +- Fixed the bug affecting the position of the input window when a + session was migrated to a linux X server with no window manager + running. + +- The color used to fill the corrupted backgrounds is converted de- + pending on the depth of remote X server. + +- The PolyFillRect() does not clean the corrupted destination region + if a stipple pixmap is used as mask. This solution is adopted to + reduce the region fragmentation and to solve the text drawing pro- + blems affecting rdesktop. + +nxagent-3.0.0-71 + +- Force a flush of the display buffer if the coalescence timeout is + expired. Set the timeout according to the link type, from 0 to 50 + ms for link MODEM. + +- In nxagentRealizeImage() the width in byte is computed newly if + the image has been scaled. + +- The shadow agent clips the screen updates in tile only if the link + type is MODEM or ISDN. + +- Split the abort conditions in the synchronization loop to check + separately the congestion and the blocking status. + +- Implemented a workaround in order to avoid graphical problems with + render composite operations on Xfree86 remote server. + +nxagent-3.0.0-70 + +- Various adjustments aimed at using the best defer rules depending + on the congestion state. + +- Fixed a problem with icons of message boxes in shadow sessions. + +- Changed the log message printed when the shadow agent can't connect + to the master session. + +- If Composite is in use, don't skip the PutImage and CopyArea opera- + tions even if the agent window is fully obscured. + +nxagent-3.0.0-69 + +- The option -nodamage prevents the shadow agent from using the damage + extension. + +- Changed the scaling feature to set the byte order of the source + image according to the local endianess. + +- Changed the scaling feature in order to handle different ratios for + horizontal and vertical sizes. + +- Force the shadow sessions to be non-persistent. + +- When a pixmap background is synchronized, an expose is sent to its + owners. + +nxagent-3.0.0-68 + +- Changed the type of parameters passed to nxagentRootlessRestack in + order to be compliant with Xlib types on 64 bit platfors. + +- The nxagentCompositeRects() checks for the render operation type to + determine if the corrupted destination region must be cleared. + +nxagent-3.0.0-67 + +- Fixed a condition discarding the expose events received from the X + server. + +nxagent-3.0.0-66 + +- The corrupted resources are removed when a session suspends, and are + reallocated only at reconnection. This is aimed at avoiding synchro- + nization loops when the link is down. + +nxagent-3.0.0-65 + +- Initialize for now the tile size at 64x64 in shadow mode. + +- The height and width of the tiles used for synchronizing drawables + are set without overriding command line option 'tile'. + +- Avoid calling miWindowExposures() for empty regions. + +- Fixed a bug while clearing corrupted regions with window exposures. + +- The corrupted drawable counters are not reset if there are bitmaps + to synchronize. + +nxagent-3.0.0-64 + +- The synchronization bitmap is used only when requesting a full + drawable synchronization, otherwise the frame-buffer is used as + source. + +- Fixed some bugs in the synchronization loop. + +- Removed the remaining debug output. + +nxagent-3.0.0-63 + +- Don't start the synchronization loop if the wakeup handler found + some clients ready. + +- Don't flush the display buffers if the synchronization was inter- + rupted and there are more drawables to synchronize. + +- Changed the backing store functions to not save the obscured areas + which are inside the corrupted region of a window. + +- Added the code to send the XClearArea() commands in shadow mode at + the end of the synchronization loop. In this way large images are + still split in tiles but, on fast links, the final result can made + visible all at once. + +- Modified the corrupted drawable counters to only report the number + of resources needing synchronization. This allows the block hand- + ler to avoid spinning through the synchronization loop if there is + nothing to do. + +- On a window exposure remove the corrupted region of the destinat- + ion window. + +- For testing purposes, the pixmap synchronization loop starts only + if there are corrupted backgrounds. + +nxagent-3.0.0-62 + +- The image scaling is applied only if the destination drawable is the + pixmap shadowing the frame buffer of the master session. + +- The shadow agent exits with a fatal error if it can't connect to the + master session. + +nxagent-3.0.0-61 + +- Forward the SIGCHLD to the NX transport instead of letting the NX + transport forward the signal to us. This allows the agent to set + and replace the signal handler at any time, without having to ta- + ke care of the state of the NX transport. + +- Improved the synchronization loop by implementing a simple round- + robin mechanism between the resources needing synchronization. + +nxagent-3.0.0-60 + +- Use a new set of functions to install, post-install and reset the + signal handlers. + +- Reset the signal handlers to their initial state after a display + failure, as part of the disconnection procedure. + +- Don't set SA_RESTART in the sigaction flags. Make the signal int- + errupt the system call. + +- Terminate all the running dialogs before exiting. + +nxagent-3.0.0-59 + +- Use the value of nxagentCongestion in nxagentUserInput() instead + of calling NXDisplayCongestion(). + +nxagent-3.0.0-58 + +- The clip mask of the scratch GC used by nxagentDeferCopyArea() is + reset before releasing the GC. + +- The MotionNotify event can now break the synchronization loop. + +- In the case of shadow sessions, if synchronization aborts then the + remaining data to synchronize are not stored in a bitmap. + +- If a table rebuild occurs in a loop searching for resources, the + loop restarts from beginning not to use the out of date table. + +nxagent-3.0.0-57 + +- The synchronization bitmap is created only if the corrupted area + of the source drawable is visible. + +- The synchronization loop skips the last synchronizing drawable to + give a chance to the next resources to be synchronized. + +- Removed the session starting infos concerning the mismatching ver- + sions of render and the window manager detection. + +- Split the gliph lists in Render.c only if the symbol SPLIT_GLYPH_- + LISTS is defined. + +- Read again the events in the block handler after the flush. + +- The nxagentCongestion variable is now a value ranging from 0 to 9, + not a boolean flag. + +- Added some experimental code dynamically reducing the size of the + display output buffer when the agent is blocking for write. + +nxagent-3.0.0-56 + +- The synchronization loop is now aborted when a short timeout exp- + ires. If the drawable synchronization cannot be completed, the + remaining data is stored in a bitmap. The synchronization loop is + then restarted using the data from the bitmap, instead of pulling + the latest image from the framebuffer. This allows the agent to + show a complete frame when displaying videos and animations, while + at the same time giving a chance to the clients to update the + screen in background. When an image from the saved bitmap is put + on the remote display, the image is compared with the actual data + in the framebuffer. If the two bitmaps match, the corresponding + region of the drawable is marked as synchronized, otherwise the + drawable remains dirty and will be synchronized at the next loop + using the new data taken from the framebuffer. + +- If the smart schedules is enabled, let the dispatcher decide when + it is time to yield and process the next client. + +nxagent-3.0.0-55 + +- Disable the smart scheduler in the case of shadow sessions. + +- If the smart scheduler is enabled, stop the timer before returning + from the block handler. WaitForSomething() sets a zero timeout if + there are clients with input but doesn't stop the timer. The select + is then interrupted to update the schedule time even if, what the + dispatcher cares, is only the ticks count at the time the client + is scheduled in. + +- Fixed a compilation warning in NXresource.c. + +- The main window of the shadow agent is mapped in nxagentMapDefault- + Windows, like for non shadow agents, if the remote display has no + window manager running. This avoids a flickering effect on the !M + logo having place if the shadow session was displayed from a Wind- + ows client. + +- Some code related to the use of the Composite extension is not built + in the agent being not necessary anymore. + +nxagent-3.0.0-54 + +- Get SmartScheduleStopTimer() from dixstruct.h. + +- Updated the NoMachine icon file. + +nxagent-3.0.0-53 + +- Changed the message 'NXAGENT: Fatal IO error on display' into 'Info: + Disconnected from display'. + +- Fix a problem occurring when the FindClientResourcesByType() needs + to reallocate the resource table. + +- The popup window synchronization breaks if an user input is caught. + +- Implemented FR05E01712. The stderr and stdin are redirected to the + 'clients' file in the session directory. + +- The nxagentRealizeImage function does nothing if the agent is not + connected to the display. + +- Removed the code implementing the redraws of the viewport frame. + Such code is not needed because is't enough for the agent to handle + the expose event received from the X server. + +nxagent-3.0.0-52 + +- Where it is necessary to wrap the function PaintWindowBackground, + the original function pointer is saved and restored afterwards. This + let other code wrapping that function (e.g. the damage extension) to + work correctly. + +- If the agent works in shadow mode, the defer parameters are ignored. + +nxagent-3.0.0-51 + +- Use the smart scheduler on platforms where it is enabled. + +- Check ClientsWithInput in the wakeup handler and update the number + of clients ready if any descriptor is set. + +nxagent-3.0.0-50 + +- Fixed TR05E01714. Changed VisibilityNotify event so that it forces + a refresh on the root window, but only if on the agent Composite is + enabled and its window moves from a VisibilityFullyObscured to ano- + ther state. + +- Grant the availability of core fonts in master sessions also after + the disconnection. This makes possible to start new clients inside + a shadow sessions while the master is down. + +- Changed nxagentGlyphs() to send a single glyph list per request. + +- Major rewrite of the agent dispatch handler. + +- Some name changes to the functions handling the session states. + +nxagent-3.0.0-49 + +- Made the dispatch loop yield control to a different client after a + fair amount of time even if the current client doesn't produce any + output. + +nxagent-3.0.0-48 + +- Modified the message in the suspend dialog to say 'Disconnect' in + place of 'Suspend'. + +- Added macros in Pixels.h to determine the behavior of the lazy en- + coding. + +- Changed the copyright attribution from Medialogic to NoMachine. + +- Reset all options to their defaults before processing the session + arguments. This fixes the problem with the DeferLevel option not + being set at reconnection. + +nxagent-3.0.0-47 + +- Initialized the arguments of NXGetControlParameters(), NXGetShmem- + Parameters() and NXGetUnpackParameters() to end up with valid data + also in the case of a display failure. + +- Converted the coordinates in the X_PolyFill requests to relative + mode. This makes all the requests independent from the origin and + helps the caching by the proxy. + +nxagent-3.0.0-46 + +- Don't print the 'Display failure' message on a SIGTERM. + +- Ensure that the NX transport is shut down after the 'Terminating + session at...' message if the session is killed by the user. + +- Let the agent filter the error output by setting the OsVendorVEr- + rorFProc function pointer. + +- Give the possibility to the agent to redirect the standard error + during a Popen() or a System() by setting the OsVendorStartRedir- + ectErrorFProc and OsVendorEndRedirectErrorFProc function pointers. + +- Fixed a problem in nxagentPolyFillRect() not properly propagating + to the destination. + +- Added nxagentPolyFillRect() and nxagentGlyphs() among the funct- + ions increasing the pixmaps usage counter. + +- Cleaned up some of the FIXME related to the lazy encoding. + +nxagent-3.0.0-45 + +- Use the three distinct functions in nxcompext to query the state + of the display connection. + +- Terminate gracefully on a fatal server error by printing the fol- + lowing in the session log: + + Error: Aborting session with 'Error text...'. + Session: Aborting session at '...'. + Session: Session aborted at '...'. + +- Removed more debug messages from the session log. + +nxagent-3.0.0-44 + +- Guess whether to compress an image with a lossless encoder based + also on the width and height, not only on size. + +- Corrupted pixmaps used as tiles propagate the dirty area when they + are involved in a PolyFillRect() operation. + +- On link settings ADSL to LAN, images are not split in tiles to bet- + ter fill all the available bandwidth. + +- Pixmaps referenced often as source in deferred operations or used + as backgrounds, are now synchronized as long as when the network + congestion level remains 0. + +- Use nxagentPaintWindowBorder() to update the window's border in + the framebuffer. + +- Fixed a problem with the new handling of the X_RenderChangePicture + requests that caused the text to be erroneously clipped. + +nxagent-3.0.0-43 + +- Don't pass the uid of the shared memory segment to the nxcompshad + library if it can't be retrieved from the options. + +- Fixed the new handling of the RenderChangePicture requests to work + on 64 bit platforms. + +nxagent-3.0.0-42 + +- Added support for the 'lossy', 'lossless' and 'adaptive' pack me- + thod literals. These values activate the dynamic selection of the + pack method by the agent. + +- Use the newer constant PACK_NONE instead of NO_PACK. + +nxagent-3.0.0-41 + +- Fixed a bug in the disconnection procedure introduced with the new + handling of the display events. + +- Realize the XRenderChangePicture() request only if a change of the + remote picture's attributes is detected. + +nxagent-3.0.0-40 + +- Dynamically select a lossy or a lossless encoder based on the num- + ber of pixels that appear to be different in the image. + +- Use the new PACK_BITMAP_16M_COLORS image encoding. Handle the case + when the packed image data points at the same data as the original + image. This is useful to save a copy. + +- The PACK_BITMAP_16M_COLORS method is now the default for lossless + encoding. + +- Don't use compression for the alpha channel. This is also intended + to better leverage the stream compression. + +nxagent-3.0.0-39 + +- The nxagentComposite() function doesn't check the source and mask + synchronization status, but defers the XRenderComposite() operation + by checking the defer level only. + +- If the target of an XCompositeText() function is an hidden window, + the operation is prevented. + +- Passing the uid of master X server process to nxcompshad library. + +- Before the call of XRenderAddGlyphs(), call the new library function + XRenderCleanGlyphs() cleaning the padding bytes of data section of + request. + +nxagent-3.0.0-38 + +- Don't warp the cursor if the requesting client is a shadow agent. + +- Changed a call to NXFlushDisplay in order to align to nxcomp version + 3.0.0-15. + +- Updated the NoMachine icon file. + +- Changed Agent.h in order to include NX version of Xlib.h avoiding + missing declarations. + +- If the NXDisplayCongestion notifies an optimum congestion state, + the continuous user input, due to unreleased buttons/keys, doesn't + break the drawable's synchronization. + +- Renamed the option 'block' as 'tile'. + +- Implemented a way to guess if the destination drawable of a copy + area is a popup window. In such a case, the source is synchronized + before doing the copy to avoid ugly effects like text items floating + on an invisible background. + +- In order to reduce the number of clip mask changings, if the clean + region of a corrupted source drawable is formed by a single rectan- + gle, its coordinates are used to change extents and position of the + area involved in the copy area operation. + +- Fixed a crash caused by a reference to a resource table freed by a + table rebuilding. This was happening because during the pixmap re- + connection some new GC resources went beyond the resource table li- + mit, causing a table relocation. As a general rule, a function loop- + ing across a resource table should not add or remove resources. + +nxagent-3.0.0-37 + +- To improve the efficiency of the algorithm deferring the trapezoid + operations, the composite does not propagate the glyphs flag to + the destination. + +- Moved the replacement of XCheckIfEvent() to nx-X11 with the name + XCheckIfEventNoFlush(). + +nxagent-3.0.0-36 + +- Changed nxagentDisplayFlushHandler() according to the new semantic + of the handler. The function is called by nxcomp when new data is + sent to the remote proxy. + +- After the flush handler is called, use NXQueryDisplay() with query + type NXDisplayCongestion to update the congestion flag. + +- Modified the boxes list defragmentation to merge only those rectan- + gles which fully overlap. + +- During the synchronization loop the nxagentDispatchHandler() takes + care of reading the enqueued events, while the nxagentUserInput() + checks only for state changes due to a processed key/button event. + +- Set the display output buffer size according to the link type. + +- Removed the congestion and synchronization callbacks. + +nxagent-3.0.0-35 + +- In order to avoid the lossy encoding of text regions, the nxagent- + GlyphsExtents is computed even if the mask format is not specified. + In this case, the render implementation was not calculating the ex- + tents of composite text operation, whose coordinates are useful only + to build a mask pixmap. + +nxagent-3.0.0-34 + +- Removed message 'Could not init font path element' from the output. + +- Moved initialization of picture support before the call to miDCInit- + ialize in the screen opening procedure. This is because miDCInitial- + ize calls DamageSetup that wraps the picture screen functions. + +- Implemented FR05E01686. Added option 'menu' enabling/disabling the + pulldown menu in the rootless agent. + +- Added a flag to each drawable to record if they have been the dest- + ination of a glyph operation. This is used to skip the deferral of + some operations (e.g. render trapezoids) if they can cause the + drawable to be synchronized using a lossy encoding. + +- The render trapezoids are deferred if the operation falls inside + a dirty region or if the destination drawable does not contain + glyphs. + +- Imported the NXmitrap.c file from render directory. + +- Improved the algorithm queuing multiple writes across a proxy + flush. + +nxagent-3.0.0-33 + +- Read the event queue after each request processed. Doing this + is expensive but it seems to work best. + +- Don't split the big trapezoid requests. Splitting the requests + doesn't seem to provide any benefit with the clients tested. + +- By defining BLOCKS in Handlers.c, Events.c and NXdispatch.c, log + the begin and end of the most sensitive routines. + +nxagent-3.0.0-32 + +- Use NXSetDisplayWriteHandler() to register a callback invoked + by Xlib after some data is written to the display socket. This + callback allows the agent to better determine when it is time + to send the sync requests. + +nxagent-3.0.0-31 + +- The operation of adding glyphs to remote glyphset has been defer- + red, in order to avoid to add unused glyphs. When a composite text + operation looks for a certain glyph, if it has not been added to + the selected glyphset, an XRenderAddglyphs is requested. + +- The forced synchronization timeout is now dependant on link type. + +- Force the mi to process the events just after having processed + any input. + +- Added an experimental 'hard' sync request intended to wait for + the X server to complete an image operation. This also affects + the agent only when the NX transport is not running. + +- Added a synchronization mechanism intended to let the agent de- + tect if the X server is not able to process its input when the + NX transport is not activated. The algorithm uses asynchronous + X_GetInputFocus replies to minimize the impact of latency on + slow connections. A new request is sent at any given amount of + bytes read from our clients. When the number of pending replies + is exceeded, the agent stops accepting additional requests and + waits for the remote until the number of pending replies returns + below the limit. Note that when the NX transport is running, the + algorithm is disabled to not interfere with the proxy's own + token-based flow control. + +- Added the nxagentDispatchHandler() function. It is called by the + dispatcher after a client's request has been processed. + +- Added the nxagentWaitEvents() function. It blocks waiting for + more input with an optional timeout. It handles the case when + the NX transport is not running and is able to recover gracely + from a display failure by returning the error. + +- Replaced most of the code that was relying on NXTransContinue() + to use the new function. + +- Moved the new event-related functions to Events.h and Events.c. + +- Disabled the code raising the splash screen at reconnection. + +- Reverted change done in 3.0.0-8 version, dealing with expose events + not having entries in the queue. They are not collected in a global + region but sent immediately. + +nxagent-3.0.0-30 + +- Let the block handler check if there are events queued after the + flush before entering the select. + +- Changed the dispatch loop to read the incoming events more often. + +- Added the nxagentReadEvents() and nxagentCheckEvents() functions. + Differently from XCheckIfEvent(), nxagentCheckEvents() doesn't + flush the output buffer if no event is available. nxagentReadEv- + ents(), instead, it's like XEventsQueued() but forces the use of + the QueuedAfterReading mode. These functions should be used when- + ever XEventsQueued() and XCheckIfEvent() would be required. + +- The nxagentQueuedEvents() macro uses XQLength() to return the + number of events that have been read and need to be dispatched. + +- The nxagentPendingEvents() function returns true if there is any + event queued. If not, it queries the transport to find if more + events can be read. + +- Ripristinated the code preventing the agent to connect to its own + display. The code was disabled while migrating to the new tree. + +- Removed the dependencies from the NXAGENT_QUERYBSIZE, NXAGENT_NO- + EXPOSEOPTIMIZE and NXAGENT_ONEXIT. Removed the unused code. + +- Removed more unused code in Clipboard.c. + +- The shadow agent calls NXShadowDestroy before exiting. + +- Reverted a change done in 3.0.0-8 dealing with expose events. If the + result of the subtraction is not sent immediately, some duplicated + refresh is shown. + +nxagent-3.0.0-29 + +- The splash screen is removed as soon as the session is started in + the case of shadow session. + +- The rules to verify when the synchronization loop can be stopped + are specified by means of a bitmask passed as parameter to synch- + ronization functions. + +- The glyphsets are no longer reconnected during a session resuming, + but only when they are used. + +- Initialized the timeout parameter in block handlers in case of NULL + value. + +- Added option 'block' to specify the size of image slices sent during + the synchronization. + +- Fixed a memory leak in nxagentParseOptions(). + +nxagent-3.0.0-28 + +- Improved the nxagentGetOptimizedRegionBoxes() function to optimize + the high fragmented rectangle lists. + +- When resizing nxagent window the fictitious resize for all top level + windows, triggering the window tree validation, is not executed if + rootless mode is off. + +- The nxagentInputWindows cannot be resized in rootless mode because + they are not created. + +- Added NXdamage.c to the source files. + +- Changed damage's GCOps functions drawing text. This was needed be- + cause the original functions didn't call agent GCOps if the drawable + was registered for damage events. + +nxagent-3.0.0-27 + +- Fixed TR04E01677. Changed the reconnection procedure to call the + function destroying the NoMachine splash window. It rarely happened + that the splash window was not removed after resuming a session. + +- Ignored the ForceScreenSaver requested by X clients to avoid clashes + with our screen saver handling. + +- Cleanup of code handling the screen saver timeout to remove referen- + ces to the old drawable's synchronization method. + +- Fixed TR04E01664. The session is terminated instead of suspended if + the auto-disconnect timeout expires and the persistence is not allo- + wed. + +- Reverted an optimization in nxagentCheckWindowConfiguration() in + order to avoid inconsistencies in the stacking order. + +- Fixed a segmentation fault in rootless mode. + +nxagent-3.0.0-26 + +- Some fixes to build in the Cygwin environment. + +nxagent-3.0.0-25 + +- Renamed the option 'lazylevel' to 'defer'. + +- Added a flag to windows to know if they have transparent children, + in order to reduce to minimum the put images on windows covered by + their children. + +- Created a generic list of graphic contexts, used when synchronizing + drawables between the nxagent and the remote X server. All the GCs + are created with IncludeInferiors property. This solves problem when + trying to synchronize windows covered by children with transparent + backgrounds. + +- The nxagentUserInput checks if keys are pressed. + +- Fixed some memory leaks. + +- In shadow mode, removed the handling of events of the source display + from the code. They can be handled in the nxcompshad library. + +- In shadow mode, allow the synchronization loop to break in case of + input event. + +- Moved the call to miDCInitialize after the initialization of poin- + ters to screen functions. This was needed to make DAMAGE work pro- + perly. + +- In shadow mode, not breaking the polling if a mouse button is down. + +- In shadow mode, allow events to break the loop sending updates. + +- At reconnection the input window is raised after the root window is + mapped. + +- Fixed an invalid read. The call to the function nxagentSetInstalled- + ColormapWindows() has been moved from nxagentDestroyWindow to Dele- + teWindow. + +nxagent-3.0.0-24 + +- The corrupted drawables are added to dedicated lists of resources + to speed up the synchronization process. + +- The nxagentUserInput checks if a mouse button is pressed. + +- Created the nxagentGetScratchGC which resets the scratch GCs to de- + faults values also on the remote X server. + +- The synchronization cycle is forced when a timeout expires, albeit + the remote display is blocked. + +- Added a parameter to synchronization functions to specify if loops + can break. It's useful to force the synchronization in some circum- + stances. + +- Keystroke CTRL-ALT-R is enabled in shadow mode too. It is used to + switch scaled and non-scaled modes. + +- Some changes to adjust the window position. + +- Moved some macros to Misc.h. + +- Some changes to adjust the behaviour of scaling feature in case of + resize and switch to full screen. + +- Freeing the buffer used for scaling if no needed anymore. + +nxagent-3.0.0-23 + +- Fixed TR02E01648 and TR10D01534. Changed pointer motion events han- + dling. In desktop mode the nxagent creates a InputOnly window that + collects the MotionNotify events. This window is mapped over the + root window. In rootless mode the nxagent creates all windows on + real X server with PointerMotionMask. + +- Not exiting from the block handler with zero timeout if drawables to + be synchronized are pixmaps only. + +- Reduced the margin around the glyph extent from 5 to 3 pixels. + +nxagent-3.0.0-22 + +- Fixed initialization of XImage used for scaling. + +- Changes to fix the position of the shadow main window. + +nxagent-3.0.0-21 + +- Moved the implementation of scaling feature in nxagentRealizeImage. + +- Disabled log message 'Font not found' in Font.c. + +- The synchronization loop is called inside the BlockHandler. Synch- + ronization goes on until the display is not blocked. + +- Exiting the BlockHandler with timeout zero if corrupted drawables + have not been synchronized because of blocked display connection. + +- Changed the synchronization loop to slice the dirty regions. + +- The updates by shadowing nxagents are now sent using the lazy me- + chanics: the remote buffer pixmap is marked as dirty, then synch- + ronized. + +- Traversing the tree to synchonize windows. + +nxagent-3.0.0-20 + +- Fixed a bug in the nxagentGetOptimizedRegionBoxes() function which + was causing a bad merging of boxes. + +- Added a margin of 5 pixels around the glyphs extents before synch- + ronizing them. + +- The synchronization cycle has been reactivated for the first lazy + level, in order to synchronize the window's background. + +- The CopyArea between pixmaps doesn't mark the full destination as + corrupted, but clips the operation with the synchronized area of the + source as happens for the windows. + +- Implemented scaling feature for the shadow agent. To do: run-time + control of this feature by keystrokes and window resize; adapting + the window size to the scaled dimensions. + +- Setting the shadow session scaling ratio equal to the size chosen + from the user divided by the size of the main session. + +- Scaled mouse motion events according with the ratio. + +- Implemented the nxagentScaleImage() function. + +- Updated version number and copyright in the output log. + +- Fixed TR06D01390. When resizing nxagent window, we make a fictitious + resize for all top level windows, in order to trigger the window + tree validation. + +nxagent-3.0.0-19 + +- Force LazyLevel to 0 in case of shadowing session. + +- If shadowing poller returns that nothing is changed and no updates + have to be sent, call WaitForSomething select with 50 ms timeout. + +- The shadow agent doesn't break the sending of updates in case of + mouse motion events. + +- The scratch GC's clip mask was not cleared during a drawable synch- + ronization. Now the GetScratchGC() function is called after changing + the nxagentGCTrap flag. + +- Implemented the function nxagentGetOptimizedRegionBoxes(). It gets + the list of boxes forming a region and operates on it to merge as + much boxes as possible, checking their width and position. + +- Implemented the function nxagentClearRegion(). It does an XClearA- + rea() for each box belonging to a region, using the color returned + by nxagentGetCorruptedRegionColor() as background of target window. + +- Implemented the function nxagentGetCorruptedRegionColor(). It gets + the color of first outer pixel in the bottom right corner of re- + gion. + +- Fixed some memory leaks. + +- Checked and removed some FIXME concerning the lazy encoding. + +- Fixed and added some debug messages in Render.c, GC.c and GCOps.c. + +- Added to the Literals.h file the Render and Shared memory requests. + +nxagent-3.0.0-18 + +- Changes to comply with nxcompshad library. + +nxagent-3.0.0-17 + +- The master agent holds the number of shadow nxagents connected to + itself. The shadow nxagent notify its presence to master nxagent + by setting the _NX_SHADOW property. + +nxagent-3.0.0-16 + +- Rearranged the lazy level rules. All the link types now use the lazy + level 1: the pixmaps are always corrupted, and they becomes synchro- + nized only when they're sources of an operation (i.e. CopyArea, ren- + der). + +- The lazy levels greater than 1 don't synchronize automatically. It's + possible to synchronize with two keystrokes: CTRL+ALT+Z forces the + windows synchronization without take care of the congestion; CTRL+ + ALT+X synchronizes the windows and the background until there is + enough bandwidth. + +- Only the tile, stipples and glyphs are always synchronized. + +- The height of glyphs region has been doubled to obtain a better vi- + sual effect after the synchronization. + +- Fixed a problem causing the background pixmaps to be used also if + they were not fully synchronized. + +- Added a function to convert a PolyPoint in a dirty region. The fun- + ction is now disabled because it is not advisable to use the exten- + ts. + +- The XCopyArea is not requested if the clip region is NIL. + +- The nxagentPutImage does not update the framebuffer when it is + doing a synchronization. + +- Moved all the code handling the drawables synchronization in the + Drawable.c file. + +- As the shared memory pixmaps are never synchronized with the re- + mote X server, now they're marked as dirty when they're created. + +- An XFillRectangles request now marks the rectangles of the desti- + nation drawable as synchronized. + +- Fixed a bug that was causing the CopyArea to propagate wrongly the + corrupted region on the destination drawable when the GC uses a + clip mask. + +- Implemented a test function useful to show on the windows all the + dirty regions as colored rectangles. It is used with the CTRL+ALT+A + keystroke. + +- Before sending the XRenderComposite operations (trapezoids, trian- + gles, TriStrip, TriFan), the drawables involved are synchronized if + they are dirties. + +- Changes to shadow mode. + +- Moved the code splitting the screen shadowing updates to a separate + function. + +- Suspend the sending of updates if input is received from the user. + +- Make use of callback mechanism implemented in the nxshadow library + to suspend screen polling when input is received from the user. + +- Flush the display link when requested by the proxy. + +nxagent-3.0.0-15 + +- Print the following info when the screen is resized: "Info: Resized + screen [<screen number>] to [<width>x<height>]. + +- Changes to comply with nxshadow library. + +- Fixed the height of screen updates in shadowing mode. + +- Terminate cleanly if shadowing initialization fails. + +- Split shadowing screen updates in smaller rectangles for slow links. + +nxagent-3.0.0-14 + +- Fixed a compilation error in NXrender.c. + +nxagent-3.0.0-13 + +- Changed the LICENSE file to state that the software is only made + available under the version 2 of the GPL. + +- Added file COPYING. + +- Updated the files imported from X.org to the 6.9.0 release. + +nxagent-3.0.0-12 + +- Fixed compilation on Sun platform. + +nxagent-3.0.0-11 + +- Implemented an algorithm adapting colors if the target display have + different depth than the shadowed display. It requires that visuals + are TrueColor and depths are 16 or 24 or 32. + +- Added the option shadowmode. If this option is '0' the shadowing + session doesn't interact with the attached session. + +nxagent-3.0.0-10 + +- Changes to comply with the nxshadow component. + +nxagent-3.0.0-9 + +- Applied changes to files imported from X.org sources. + +- Updated copyright notices to the current year. + +nxagent-3.0.0-8 + +- Imported changes up to nxagent-2.1.0-17. + +- Fixed problem with font path on Solaris 10. + +- Disabled some log messages. + +- If the agent has blocked when trying to write to the display, try to + read other events from the connection. + +- After synchronizing expose events, the result of subtraction is not + sent immediately, but added to a region. Expose events will be for- + warded to clients after exiting from the event loop. + +- Critical output is set when button mouse events are received. + +- Fixed TR12D01584. X11 sessions could not be started on Mandriva Li- + nux 2007 because of a different location of fonts. The font path + used by this distribution is now added to the alternates font paths. + +- Fixed TR11D01550. Modified the collection of visuals when nxagent + opens a display. Now we only use the ones with the same depth than + the default one set in the screen. + +- Modified the reconnection of pict-format structures, to avoid an + error that arises when migrating a session by a Linux machine to + a Windows one. + +- Small changes in handling of expose events. + +- GraphicsExpose are no more forwarded to clients immediately. They + are merged with remote-only exposures and sent later. + +- Invalidated expose queue elements dealing with destroyed windows. + +- Cleaned up code in nxagentSynchronizeExpose(). + +- Fixed TR10D01541. Now when destroing a window if lastClientWindowPtr + point to this window then in nxagentClearClipboard() we put nxagent- + ClearClipboard to NULL and lastClientStage to SelectionStageNone. + +- Fixed a problem with LazyLevel option that wasn't correctly read + from command line. + +- Fixed an arithmetic exception raised when the viewable corrupted + region is empty but not nil. + +- Removed the obsolete 'sss' option. + +- Fixed a warning related to the expose queue. + +- Modified the queue of exposed region to remove some memmov() calls. + +- Remote expose events not having entries in the queue are collected + in a global region and sent later, instead of being sent immediate- + ly. + +- Changed nxagentCheckWindowConfiguration() to prevent unuseful calls + to XQueryTree(). + +- Fixed TR10D01530. Fixed an invalid write in doOpenFont(). + +- Fixed some invalid write/read in nxagentVerifyDefaultFontPath(). + +- Fixed TR10D01518. If needed, a restack is performed on the top level + windows in rootless mode. + +- Fixed TR10D01520. Reviewed session termination and log messages in + the case of indirect XDMCP. + +- In PictureCreateDefaultFormats(), cleaned the PictFormatRec struct + when the format is not supported. + +- Fixed TR09D01498. As it is possible to use multiple paths where to + store the fonts, now the agent concatenates all the existing font + paths used in various XFree/Xorg distributions to obtain a unique + default font path. + +- Fixed TR09D01502. The privates of the real pixmap are initialized + before trying to allocate a virtual pixmap, avoiding the possibility + to access an inconsistent structure in case the allocation fails. + +- Fixed a memory leak due to a missing deallocation of a virtual pix- + map's region. + +- Fixed TR08D01486. Removed a warning in NXrender.c. + +- Implemented FR08D01470. Now in the reconnection phase missing fonts + are replaced by the most similar picked among the available ones. + +- Fixed TR08D01480. A condition inside the nxagentWindowExposures + function was ignoring the possibility that the first region para- + meter could be a null region. + +- Fixed TR06D01409. Now NXCollectGrabPointer() is called with the + owner_events true in ActivatePointerGrab() . + +- Fixed TR03D01317. Increased the time after wich the session termina- + tes. + +- Fixed TR08D01475. In rootless, ConfigureWindow requests are only + forwarded to the X server, even if no window manager has been detec- + ted. + +- Fixed TR04D01367. An XKB event is sent to notify that keyboard map- + ping has changed. + +- Check the number of regions in the list before running nxagentSynch- + ronizeExpose(). + +- Reduced the number of GCs used during the drawable synchronization. + +- Optimized the corrupted region synchronization trying to use the + extents is some circumstances instead of split the full region. + +- Checked and removed some FIXME. + +- Fixed TR05D01384. Xgl server uses less picture formats than nxagent + usually does. Now the PictFormat structures used by nxagent are fil- + tered with the ones available for the real display. + +- Fixed TR06D01410. Function nxagentRestoreAreas have to make use of + a GC with subwindow mode ClipByChildren for preventing from repaint + also children of restored window. Children are restored in a separ- + ate call, if they have backing store on. + +- Fixed TR07D01426. The cursor data were swapped in place if the dis- + play had different bitmap bit order. Let Xlib do this work on a copy + of the image, preventing from messing up the original data. + +- Fixed TR07D01450. Some fonts were missing in the list of available + fonts because the ListFonts pattern used to build this list was too + much generic. To build a full font list two different patterns have + been used. + +- Fixed TR07D01449. Some X clients might affect the X screen saver + functioning modifying the default properties. The SetScreenSaver + request now correctly checks the parameters changes to avoid any + issue. + +- Fixed TR07D01432. X11 sessions could not be started on Debian 'Etch' + because of a different location of fonts. The font path provided by + the Debian Policy is now added to the alternates font paths. + +- Fixed TR07D01437. The auto suspend timer was reset when it should + not. + +- Fixed a conditional jump on uninitialised value. + +- Fixed TR05D01380. Now migrating a session when display have a 16-bit + depth does recover all visuals, avoiding reconnection failure. + +nxagent-3.0.0-7 + +- Fixed problems occurring when the main session is terminated and the + connection is refused to the shadow agent. + +- Fixed include directory order for Solaris. + +nxagent-3.0.0-6 + +- The shadow agent works only in viewport mode. + +- Added nxagentShadowCreateMainWindow function. This function creates a + pixmap and a window for mirroring the display root window. + +- Added NXShadowUpdateBuffer() function in order to create the buffer + for the poller with the same sizes of the root window of the master + agent. + +- Added NXxrandr.c NXxrandr.h and NXxrandrint.h files. + +- If the main agent screen is resized, the shadow agent adapts to the + new size of the root window. + +- Changed option activating mirror to -S. + +- Removed usleep() call when the agent is suspended. + +- Input events are sent to the main session even if it is in sus- + pended state. + +- Updates are made from top to bottom. + +- Added the option IgnoreVisibility. If this option is set, PutImage + is not skipped when the window is fully obscured. + +- Added the option 'shadow' saying the display to attach. + +nxagent-3.0.0-5 + +- Added the mirror mode. It is activated by -M option. + +- Recovered the state of keys when the agent in access mode loses + focus in mirror mode. + +- Changes to work with 16-bit depth display in mirror mode. + +- Changed the Imakefile in order to include NXaccess.h and NXaccess- + Event.h files. + +- The layout keyboard is passed to NXShadowCreate() function in order + to load the right keymap file in mirror mode. + +nxagent-3.0.0-4 + +- Small changes to build on 64 bit x86 platform. + +nxagent-3.0.0-3 + +- Fixes to build on Cygwin platform. + +- Change the order of include directories in Imakefile. + +- Renamed GC.h, Window.h and Pixmap.h to avoid name clashes. + +- Undefined NXAGENT_UPDRADE in Composite.c and NXcomposite* files. + +- Defined ddxBeforeReset() in Init.c. + +nxagent-3.0.0-2 + +- Merged changes to NXdispatch.c, NXdixfonts.c, NXmiwindow.c, NX- + picture.c, NXproperty.c, NXrender.c, NXresource.c, NXwindow.c. + +nxagent-3.0.0-1 + +- Opened the 3.0.0 branch based on nxagent-2.0.0-88. + +nxagent-2.0.0-88 + +- Fixed a memory leak in the code handling the remote font list. + +- Removed some log message. + +nxagent-2.0.0-87 + +- The box size is checked during the region synchronization to avoid a + possible arithmetic exception. + +nxagent-2.0.0-86 + +- Checked the validity of the colormap in nxagentChangeWindowAttri- + butes(). + +nxagent-2.0.0-85 + +- Fixed the bad destination coordinates of shared memory pixmap synch- + ronization in nxagentCopyArea() and nxagentCopyPlane() functions. + +nxagent-2.0.0-84 + +- Discard the Terminate Server key sequence Ctrl-Alt-BackSpace. + +nxagent-2.0.0-83 + +- Added a workaround to prevent the use of an inconsistent client poi- + nter in the nxagentNotifyConvertFailure() function. + +nxagent-2.0.0-82 + +- Fixed the parsing of option 'backingstore'. + +nxagent-2.0.0-81 + +- The agent window visibility on the real X server is used together + with the internal state to decide if graphics operations can be + avoided. + +- When restoring areas, if the backing pixmap is corrupted, an expose + event is sent to the region that can't be restored. + +nxagent-2.0.0-80 + +- The core protocol requests internally used to accomplish a Render + extension request are no longer propagated to the real X server. To + be more precise in this way we can save many XCreatePixmap, XChange- + GC and XSetClipRectangles. + +- Corrected a minimal incoherence in nxagentCopyArea in managing the + creation and deallocation of a region. + +- Fixed a double synchronization of an aged drawable during a put ima- + ge operation, due to a missing check of nxagentSplitTrap value. + +- Added the VisibilityChangeMask bit to the event masks. + +- Improved the algorithm which prevents the server client's resource + duplication. + +nxagent-2.0.0-79 + +- Added the 'lazylevel' option usable in the command line to specify + how much the Agent should be lazy. The default level is 2. Each + level adds the following rules to the previous ones: + + Level 0 The lazy is off. + + Level 1 The put images are skipped if we were out of bandwidth, + unless that the destination drawable has an old corru- + pted region. + + Level 2 No data is put or copied on pixmaps, marking them always + as corrupted and synchronizing them on demand. + + Level 3 The put images over the windows are skipped marking the + destination as corrupted. When a copy area to a window is + requested, the source is synchronized before copying it. + + Level 4 The source drawable is no longer synchronized before a + copy area, but the operation is clipped to the synchro- + nized region. + +- Implemented a dynamic synchronization mechanism, based on user ac- + tivity: if the input devices are not used for a variable amount of + time (depending from the configured link type), the synchronization + starts and goes on until there is enough bandwidth. + +- Minor fixes to the way the copy area propagates the corrupted re- + gion. + +- Whenever a put image is done, a full synchronization is forced on + the destination drawable if it has an old corrupted region. + +- During the overall synchronization a drawable is skipped if its + timestamp is lower than the synchronization interval. + +- Updated the copy plane to skip the operations from a corrupted pix- + map to another pixmap. + +- Fixed the pixmaps synchronization which was not checking the avai- + lable bandwidth. + +- In rootless mode, ConfigureWindow requests are not internally per- + formed for top level windows if a window manager is running. Anyway + they are forwarded to the X server. + +- Enabled the DPMS extension. + +- Fixed the -dpi option. + +nxagent-2.0.0-78 + +- When the remote proxy supports the alpha encoding, the alpha data + is sent compressed. When connected to an old version, the agent + uses the NXSetUnpackAlphaCompat() call. + +- Added support for the RLE pack method. + +nxagent-2.0.0-77 + +- Fixed the check for special keystrokes. State mask for Alt and Meta + keys are inferred from the X server modifier map. + +nxagent-2.0.0-76 + +- Fixed application icon in rootless mode. + +- If SYNC_WHOLE_GLYPH_DRAWABLE is set in Render.c the whole drawables + used in the composite glyphs are synchronized. This is useful to + evaluate the policy we should use to minimize the put images. + +- Code cleanup in Pixmap.c concerning the synchronization functions. + +- Added the nxagentSynchronizeBox() function. + +- Setting a wide band link (ADSL, WAN, LAN) disables Lazy and Strea- + ming options. + +- Now the Lazy option can be switched by the Ctrl+Alt+E keystroke. + +- Set a timestamp on a drawable to verify how much old its data are. + If we didn't update it since two seconds, the put image operations + are not skipped. + +- The image data split in chunks smaller than a threshold is now mo- + ved from the nxagentPutImage() to the nxagentRealizeImage() func- + tion. If a chunk is going to be put on an hidden area of a window, + the operation is skipped. + +- Fixed the value assigned to the id of the alpha visual. Now it is + assigned by XAllocID(). + +- Removed a call to XSetInputFocus() before mapping the default win- + dows. + +- Restored the backup display pointer when failing to reconnect the + display. + +- Fixed some return value in the options parser function. + +- Fixed the parsing of environment variable. + +nxagent-2.0.0-75 + +- Optionally split the long X_RenderTrapezoid requests in multiple + messages to help the compression. + +nxagent-2.0.0-74 + +- Fixed a bug preventing the reconnection of pictures. + +- Fixed the way the agent notify its start up to NX Client. Now the + ownership of agent atom is set before the reconnection of pixmaps. + +nxagent-2.0.0-73 + +- Added a check on the display pointer in nxagentTerminateDisplay() + to ensure that we don't try to force an I/O error if the display + is already down. + +- The image operations now are clipped to the visible area of the + drawable. As this may hamper the caching algorithm, only source + images bigger than 32K are clipped. + +- Code cleanup in Render.c. + +- When setting SKIP_LOUSY_RENDER_OPERATIONS in Render.c the realiza- + tion of some operations is skipped. This is useful to determine + how clients (mis)use the RENDER extension to achieve even worse + performance than they were able to achieve using the core protocol. + +nxagent-2.0.0-72 + +- Ensured that SIGUSR1 and SIGUSR2 are ignored if the NX transport + is not running. + +nxagent-2.0.0-71 + +- Modified the following messages used to track the session state: + + From: "Session: Session starting at..." + To: "Session: Starting session at..." + + From: "Session: Session terminating at..." + To: "Session: Terminating session at..." + +nxagent-2.0.0-70 + +- Removed the obsolete 'Info' messages related to the 'fast' versus + 'slow' copy area and get image modes. The -slow and -fast options + are now ignored as ignored are the keystrokes that allowed switch- + ing between the two modes. + +- Removed more obsolete warnings and commented the logs left around + for test purposes. + +- Removed the code in NXdispatch.c handling the fake get-image. + +- Removed the flags related to the use of the frame-buffer. + +- Major code cleanup in GCOps.c, Window.c, GC.c, Pixmap.c, Screen.c. + +nxagent-2.0.0-69 + +- Added a check to avoid parsing an empty DISPLAY variable. + +- Added parsing of the 'streaming' option. + +- GetTimeInMillis() function is compiled only if DDXTIME is defined, + to avoid double definition errors on Solaris platform. + +- Messages "Suspending session..." and "Session suspended..." are not + printed if the DE_TERMINATE dispatch exception is set. + +- When synchronizing the shared memory pixmaps the image is no longer + put on the framebuffer. + +- Code cleanup in the nxagentSynhronizeRegion() function. + +- Added the 'lazy' option to enable or disable the lazy policy. It is + activated by default. At the moment this is configured at compile + time and can't be changed through a command line or the option file. + +- Fixed the counter of the corrupted backgrounds by checking if the + pixmap was already marked. + +- The option SharedPixmaps is now activated by default. + +- Fixed a problem when synchronizing the shared memory pixmaps with + the operation being erroneously skipped. + +nxagent-2.0.0-68 + +- If we are doing a copy area to a pixmap and the source drawable is + not synchronized, the destination is marked as corrupted and the co- + py area request is not propagated to the X server. As a general rule + the source drawables are now synchronized only when they are copied + to a visible window. + +- The nxagentSynchronizeRegion() function synchronizes the region one + box at a time. This solves the incorrect pictures synchronization. + +- When a new element is added to the list of exposed region, sending + the synchronization request to the X server is postponed to the next + call of nxagentFlushConfigureWindow(). + +nxagent-2.0.0-67 + +- Ensured that NXTransDestroy() is called when getting rid of the NX + transport. + +nxagent-2.0.0-66 + +- The various messages used by the NX server to control the state of + the session have been changed and the NX server will have to be mo- + dified accordingly. + + At the early startup the agent will print the following message: + + "Info: Agent running with pid '...'." + + Followed by: + + "Session: Session starting at '...'." + + The ellipsis here represent the current timestamp, as reported by + the POSIX function ctime(): + + Example: Mon May 22 15:07:11 2006. + + After the connection to the remote display has been established, + the agent will print the following message: + + "Session: Session started at '...'." + + This replaces the old messages: + + "Info: Session started, state is [SESSION_UP]." + + Or: + + "Info: XDMCP session started, state is [SESSION_UP]." + + And: + + "Info: Entering dispatch loop with exception 0x0." + + If the display connection can't be established, due to a network + failure, for example, the agent will exit with a fatal error, for + example: + + "Fatal server error: + Error: Unable to open display 'nx/nx,options=...'." + + This is a special case, as the X server is still initializing and + the agent can't intercept all the possible causes of errors. + + When suspending the session, the agent will print one of the fol- + lowing messages, depending on the reason of the disconnection: + + "Session: Suspending session at '...'." + + Or: + + "Session: Display failure detected at '...'." + "Session: Suspending session at '...'." + + As soon as the disconnection procedure is completed, the agent will + notify the server with the message: + + "Session: Session suspended at '...'." + + This message replaces the old message: + + "Session: Session suspended." + + When entering the reconnection procedure, the agent will print: + + "Session: Resuming session at '...'." + + If the session can be successfully resumed, the agent will print: + + "Session: Session resumed at '...'." + + Otherwise, if the display cannot be opened or if the proxy is not + able to negotiate the session, the agent will return in suspended + mode by printing: + + "Session: Display failure detected at '...'." + "Session: Session suspended at '...'." + + At the time the session be terminated, the agent will print: + + "Session: Session terminating at '...'." + + Followed by: + + "Session: Session terminated at '...'." + + This replaces the old message: + + Info: Exiting dispatch loop with exception 0x2. + + The message 'Session terminated at...' should be the last message + parsed by the NX server. From that moment on the NX server will + wait the agent process to ensure that the cleanup procedures are + completed without errors and that the process successfully termi- + nates with the exit code 0. + +nxagent-2.0.0-65 + +- Many improvements to the block handler and to the drawable synch- + ronization loop. + +- Anyway the synchronization loop is skipped, at the moment, to bet- + ter test the new copy area implementation. Also all the put-image + on pixmaps are skipped, so that the pixmaps are only synchronized + on demand. + +- Small fix in the put image to always use the region already allo- + cated when marking a region as corrupted. + +nxagent-2.0.0-64 + +- The realization of the put image operations now depends on the + state of the link, as reported by the proxy through the synchroni- + zation handler. If the proxy link is aproaching a congestion, the + destination area of the drawable is marked as corrupted and the + operation is skipped. + +- At the moment the synchronization strategy is quite unsophistica- + ted. The drawables are synchronized when a timeout expires in the + block handler. The synchronization loop is aborted as soon as the + link approaches again the congestion and is restarted at the next + timeout. + +- Imported miwindow.c from the DIX layer. The code has been changed + to prevent miSetShape() from trying to destroy a null region. The + bug appears to be related to the backing store but it is unclear + if can also affect the sample server. The region is allocated at + the beginning of the function only if the backing store is set for + the window. Then miSetShape() calls miChangeSaveUnder(), that, in + turn, calls miCheckSubSaveUnder(). The latter can change the back- + ing store attribute of -some- windows, including, apparently, the + window that miSetShape() is processing. miSetShape() then destroys + the region if the backing store is set, but it doesn't verify if + the region was actually allocated. The problem is fixed by simply + adding a check on the pointer. + +nxagent-2.0.0-63 + +- Added the nxagentDisplaySynchronizationHandler() callback. The NX + transport uses the callback to report when it is possible synchro- + nize the pixmaps and the other X objects that are corrupted or in- + complete. + +- Fixed nxagentClearSelection() to correctly validate the selection + owner before clearing the record. + +- Changed the NXGetControlParameters() call to reflect the changes + to the reply. + +nxagent-2.0.0-62 + +- At reconnection the pixmap data is sent to the remote X server only + in two cases: if the pixmap is associated to a picture (glyphs, for + example) or if its depth is 1 (clip masks of GCs). All the other + pixmaps are marked as corrupted and synchronized on demand as soon + as the drawable is used as a source. This code is not enabled by + default and is currently being tested. + +- Implemented a new copy area function synchronizing the corrupted + region of a drawable before using it as a source. + +- Imported resource.c from the DIX. This makes possible to avoid the + duplication of the RT_GC, RT_FONT and RT_PIXMAP resource types. + +- Added the RT_NX_GC resource type and removed the old code dealing + with the reconnection of the GCs used by the GLX extension. + +- Fixed a problem in the synchronization of the window background. + +- Checked and removed some FIXMEs related to the streaming code. + +- Changed nxagentRestoreAreas() to take care of the width of the win- + dow's border. + +- Changed nxagentSaveAreas() to be independent from the window's pos- + ition. + +- Called nxagentMapDefaultWindows() before pixmaps' reconnection. + +- Changed nxagentMapDefaultWindows() to notify the client about the + agent's startup also when running in rootless mode. + +- Added the delete and backspace keystrokes to the routine removing + duplicated keys. + +- Wehn resizing the desktop the clip region of the children windows + is clipped to the new size of the root. This fixes a crash occur- + ring when resizing the desktop to the minimum height. + +nxagent-2.0.0-61 + +- Changed the extraction of alpha channel from images to be endianess + independent. + +nxagent-2.0.0-60 + +- nxagentReleaseSplit() now uses the NXAbortSplit() request to force + the proxy to discard the pending splits. + +- Added the value of the SharedMemory and SharedPixmaps options in + the log, together with the size of the shared memory segment used + by the remote proxy. + +- Fixed the compilation problem affecting the previous version. + +- The location of xkb base directory is checked by calling _NXGetXkb- + BasePath() function. + +- Fixed TR05D01371. nxagentVerifyDefaultFontPath() is called only if + the default font path is not defined on the command line. + +- Removed some log message. + +nxagent-2.0.0-59 + +- Improved the composite text operation to synchronize the regions + affected by the operation instead of the whole drawable. + +- Updated the copy plane to better propagate the corrupted region + to the destination. + +- The background pixmaps are synchronized with a deferred strategy. + Tiles and stipples are still synchronized as soon as the GC needs + to be used. + +- Completed the new copy area implementation. + +- Shared memory pixmaps are not synchronized after a RenderChange- + Picture operation. This needs further testing. + +- Added a nxagentNotifyKeyboardChanges() function that sends a Map- + pingNotify event to clients when the keyboard is reloaded or re- + configured. The SendMappingNotify() function is not used anymore. + This hopefully solves the TR01D01284. + +- Moved the nxagentResetKeyboard() function in Keyboard.c. + +- Checked if the previous sibling of a window is changed before try- + ing to restack it. This saves the redundant window configuration + requests of the previous version. + +nxagent-2.0.0-58 + +- Before composite glyphs operations, only areas intersecting the + glyphs extents are synchronized. + +- When a new split resource is allocated, a copy of the GC used by + the put image operation is created. Such copy will be safely used + by the commit operation even if the original GC is changed or + destroyed. + +nxagent-2.0.0-57 + +- Region saved by the backing store and corrupted region of backing + store pixmaps are emptied at suspend and resume time. This makes + the exposures go to the clients that will redraw their windows. + +- Changed the nxagent root window cursor. The cursor of the parent + window is used instead of the default 'X' cursor. + +nxagent-2.0.0-56 + +- Rewritten the state machine handling the streaming of the images. + +- By calling FatalError(), the normal server shutdown was skipped + and left the X server socket in .X11-unix. This happened also if + for any reason the agent couldn't complete the session startup. + Now the DDX abort routine, if the agent is not exiting because of + an exception, calls nxagentAbortDisplay() which closes down the + well known sockets. + +- Upon a failure of the reconnection procedure, if the alert shown + to the user by leveraging the proxy control channel is not set + to a valid code, the function in will use a default. + +nxagent-2.0.0-55 + +- Added an explicit link flush in the display block handler. The + block handler should now be called by nx-X11 before entering the + select, not only the the agent has entered WaitForReadable() or + WaitForWritable(). + +- Removed the checks on the value of the Streaming option. The way + a drawable is treated only depends from its previous state. + +- Started reimplementing the copy area operation to better propaga- + te the corrupted region to the destination. + +- Shared pixmaps are now synchronized before a copy plane operation. + +- The unpack alpha is discarded before the drawable synchronization. + This fixes the problems with the synchronization of the cursor. A + better way to deal with the condition is to be considered for the + future. + +- Added a check in the nxagentPutImage() function to skip the opera- + tion if the window is fully obscured. + +nxagent-2.0.0-54 + +- Fixed a bug in nxagentPaintWindowBackground(). A region passed as + parameter was modified by this function and this affected subseq- + uent operations involving the region. + +- In rootless mode, the map state of a top level window is uncondit- + ionally reflected in the internal state when receiving a map event + from the real display. + +nxagent-2.0.0-53 + +- Regions are marked as synchronized after an image operation if the + image didn't generate a split. + +- When an image operation takes place on a drawable which is already + being streamed, the resource is marked as invalid and the commits + are discarded. + +- A specific trap is used at the time a drawable is synchronized. + +- Fixed Render.c to use the latest streaming code. + +nxagent-2.0.0-52 + +- Fixed a problem in rootless mode where some windows could have mis- + sed to update the mapped flag after a MapNotify event. + +nxagent-2.0.0-51 + +- Realization of images is skipped, if the link is down, and a small + delay is introduced before returning from the image function. + +- Started implementing a new handler to let the agent include arbit- + rary data in the transport statistics. For now, only the interfa- + ces and the stubs exist, and the handler is not registered to the + proxy. + +nxagent-2.0.0-50 + +- Removed the unused code in nxagentCheckPixmapIntegrity(). + +- Instead of calling nxagentShapeWindow() immediately, windows to be + reshaped are added to the list of windows that have to be configur- + ed at later time. This allows SaveAreas() to work even when windows + change shape, as in the case of the "bouncing cursor" as implement- + ed in some versions of the KDE. + +- Added a missing call to nxagentFlushConfigureWindow() in the recon- + nection procedure. + +nxagent-2.0.0-49 + +- Code cleanup in the lazy encoding. Implemented distinct utilities + to allocate the split resources and manage the corrupted areas. + +- The Render.c file is taken from the previous version because the + updates break the composite code. + +- Renamed the option 'Lazy' to 'Streaming'. + +nxagent-2.0.0-48 + +- Made the image cache use the agent data, instead of allocating and + copying. + +- Fixed a memory leak in the image routines. + +- The image cache is freed at exit. This helps investigating other + eventual leaks. + +nxagent-2.0.0-47 + +- Solved the problem at reconnection with lazy encoding enabled. + +nxagent-2.0.0-46 + +- Solved a bug in the parsing of the pack method that made the agent + select an unavailable id. + +nxagent-2.0.0-45 + +- Ensured that images are explicitly byte swapped before sending to + an X server using a different byte order. In the attempt of saving + an expensive operation, the previous code let the unpack procedure + do the job, but this could fail to work in some special cases. + +- Cleaned the bitmaps used for the core cursors before putting the + image. + +- Left the display error handler installed during all the lifetime + of the session so that other parts of the code don't have to inst- + all it explicitly before entering a critical Xlib routine. + +- Removed more unused code. + +nxagent-2.0.0-44 + +- Fixed the problem with the cursor image being encoded with a lossy + method. The fix is a temporary. The final solution requires changes + to the lazy encoding. + +- Reworked the code dealing with the alpha visual. The color mask is + set based on the endianess of the remote display and is recreated + after a session resume. + +- Removed more unused code. + +nxagent-2.0.0-43 + +- Corrupted regions are now correctly clipped to the visible area of + the drawable. + +- Fixed a problem with the clip mask when calculating the intersect- + ion of the clip region with the destination region. + +- Drawables involved in a composite glyph operation are now synchro- + nized prior to being used. + +- The nxagentRealizeDrawable() function is now called only for draw- + ables that are not already synchronized. + +- Pixmaps are now skipped in the synchronization loop. Synchronizat- + ion of pixmap is to be implemented. + +nxagent-2.0.0-42 + +- Improved the algorithm removing the duplicated keys by trying to + read more events. + +nxagent-2.0.0-41 + +- Made use of the NXFinishSplit() request to speed up the completion + of a pending split. + +- Added an explicit NX transport flush before any operation that may + block waiting for data from the X server. + +- Set the NX flush policy to deferred after reconnection. + +- Solved refresh problems when reconnecting in rootless mode. + +- Modified the routine removing duplicated arrow key events. Now the + routine deals with page down and page up keys as well. + +- Added a check for xkb base directory path, in order to support new + Linux distributions. + +- Disabled backing store support for rootless sessions, as implement- + ation is not very functional, yet. + +nxagent-2.0.0-40 + +- Removed code related to old managing of backing store. + +- Added initialization of backing store by calling miInitializeBack- + ingStore(). + +- Implemented nxagentSaveAreas() and nxagentRestoreAreas() functions. + These functions are based on fb code. Calls to XCopyArea() have been + added in their implementation to make them be effective also on the + real X server. + +- Instead of calling nxagentConfigureWindow() in ClipNotify() and + PositionWindow(), windows to be configured or mapped are added to a + list, together with a mask storing operation that have to be done. + Windows in the list will be configured or mapped later by calling + nxagentFlushConfigureWindow(). This avoids that windows were mapped + or configured before saving areas in the backing store pixmaps. + +- The function nxagentFlushConfigureWindow() is called before resto- + ring areas on the X server in nxagentRestoreAreas() and at the end + of ConfigureWindow and MapWindow in the DIX layer. + +- Blocked the NoExpose events at the proxy side. + +- Fixed an error in nxagentCompareRegions(). + +nxagent-2.0.0-39 + +- Ensured that the display errors are detected while waiting for a + split operation to complete. + +- Removed more unused code. + +nxagent-2.0.0-38 + +- Changed nxagentSetCursorPosition() to avoid warping the cursor if + the requesting client is NULL or the serverClient. + +- Added a specific trap to avoid compressing an image associated to + a RENDER cursor using a lossy encoding. + +nxagent-2.0.0-37 + +- Added a check in nxagentPaintWindowBackground() to avoid calling of + XClearArea() if the window is not realized. + +- Modified nxagentAtomNames in Atoms.c to include CLIPBOARD and TIME- + STAMP atoms, avoiding further calls to XInternAtom in Clipboard.c. + +- Solved TR04D01356. Auto repeat mode setting is no more propagated to + the X server keyboard. + +- Cleaned up the code in the routine removing duplicated arrow key + events. + +nxagent-2.0.0-36 + +- Added the Literals.h file. For now it just contains a table used + to translate a request opcode to the name of the X request, to be + used for test purposes. + +nxagent-2.0.0-35 + +- Major code rewrite in nxagentPutSubImage(). Removed support for the + deprecated image encodings. Ensured that padding bytes are cleaned + before trying to locate the image in the nxcompext cache. Avoided + to store the image in the cache if it is coming from a XVideo or + GLX operation. + +- Added support for the new RGB image encoder. This allows the agent + to use the simplest encoding by still separating the alpha channel + from the image data. + +- Added the missing check in nxagentRedirectWindow() verifying that + use of the composite extension is enabled. + +- Updated to use the new NXCleanImage() function. + +- Removed more debugging output. + +nxagent-2.0.0-34 + +- Updated to use the 'what' parameter in NXFlushDisplay(). + +- Removed the duplicated arrow key events from the event queue. + +- Solved the TR04D01355. The X11 agent now tries to locate the + fonts.dir file in the misc directory, to verify the validity of + the font path. + +- Added a check in nxagentChangeClip to avoid creating a new clip + mask if the old clip mask matches the former. + +- Use the 'fixed' font to replace fonts that are not found a the + display reconnection. This should overcome one the most common + sources of troubles when migrating the session to a different + display, and constitute the base for improving the algorithm + trying to match a substitute font. + +- Implemented the FR04D01360. Now the user can enable/disable the + streaming of the images by using the option 'streaming'. + +- Implemented the FR04D01358. The backing-store can be enabled or + disabled by using the option 'backingstore'. + +- Forced the reconnection routine to call the IOError handler in + the case the display cannot be opened. + +nxagent-2.0.0-33 + +- The GetImage requests in 'slow' mode are now served by retrieving + the content of the drawable from the frame buffer. + +- Replaced a call to XQueryExtension() by one to XRenderQueryExten- + sion(). This function caches previous QueryExtension requests. This + partially implements FR01D01275. + +- At reconnection, the keyboard is reset only if the keyboard option + has been changed. + +- Fixed the fonts reconnection procedure. Now the remote fonts list + is refilled before fonts reconnection and after failed fonts + reconnection, so as to store the correct list of available fonts. + +- Added a check in nxagentLoadQueryFont to look up selected font in + the list of available fonts. This check avoid filling FontStruct + with invalid data. + +- Added TIMESTAMP to handled selection targets. + +nxagent-2.0.0-32 + +- Implemented FR03D01323. Added the 'clipboard' option to enable or + disable copy and paste operations from the user's desktop to the NX + session or vice versa. This option can take four values: + + client The content copied on the client can be pasted inside the + NX session. + + server The content copied inside the NX session can be pasted + on the client. + + both The copy & paste operations are allowed both between the + client and the NX session and viceversa. + + none The copy&paste operations between the client and the NX + session are never allowed. + +nxagent-2.0.0-31 + +- Implemented FR03D01337. Now the X11 agent is able to read the op- + tions from different places according to the following order: the + DISPLAY variable, the options file, the command line. + +- Implemented FR03D01347. Added 'composite' to parsed options. + +- Always activate shared memory support in the remote X server proxy. + +- Modified nxagentCopyArea for the case the source is a shared memory + pixmap. The pixmap on the X server is not synchronized, but the con- + tent of the shared pixmap mantained by the agent is placed directly + on the destination drawable. This allows to skip the following Copy- + Area operation. + +nxagent-2.0.0-30 + +- Added the missing flush of the Xlib buffer at the beginning of + the block handler. + +nxagent-2.0.0-29 + +- Changes in the block and wakeup handlers to queue multiple reads + and flush the link on demand. + +- Removed the unused code in Control.h and Control.c. Renamed the + files as Client.h and Client.c. + +- Added support for the '-nocomposite' command line option. + +nxagent-2.0.0-28 + +- Moved the composite code to Composite.h and Composite.c. + +- Redirected the top-level windows when running in rootless mode. + +nxagent-2.0.0-27 + +- When the composite extension is supported by the remote display, + the agent window is redirected to the off-screen memory of the + X server. + +- Imported Xcomposite.c, Xcomposite.h and xcompositeint.h from the + 3.0.0 branch to be able to activate the off-screen redirection of + the top level windows. + +- Added Composite to the list of agent options. The default is to + use the composite extension, when available. + +nxagent-2.0.0-26 + +- Avoided to suspend the clients on excess of karma or after a get + input focus request. + +- Images are now split only when the agent is in congestion state. + +- Moved all the image related functions from GCOps.h and GCOps.c to + Image.h and Image.c. + +- Removed the unused includes in GCOps.c and Image.c. + +- Added the karma delay field to the NXGetControlParameters() call. + +- Renamed placeholder.xpm as nxmissing.xpm. Renamed the Icon.h file + as Icons.h. Added there a define to point at nxmissing.xpm in the + include. + +nxagent-2.0.0-25 + +- Implemented the FR03D01334. Option keyboard is now a synonym of + option kbtype. + +nxagent-2.0.0-24 + +- Ensured that the split procedure is completed before executing a + render operation that required a synchronization of a shared mem- + ory pixmap. + +- Added the appropriate checks to avoid synchronizing the same sha- + red memory pixmap multiple times. + +nxagent-2.0.0-23 + +- Imported changes to NXrender.c and NXshm.c in the files for the + 3.0.0 port. + +nxagent-2.0.0-22 + +- Implemented FR03D01331. Options shpix and shmem enable/disable the + use of shared pixmaps and shared memory extension. + +- Implented handling of value "query" for nxagentKbtype. This value + is passed by the NX client for MacOSX. If value of nxagentKbtype is + "query" or NULL we init keyboard by core protocol functions reading + the keyvoard mapping of the X server. The property _XKB_RULES_NAMES + is always set on the root window with default values of model and + layout. + +- Fixed TR11C01223. When the XDM connection can't be established the + agent creates an alert to notify the user that XDM session failed + to start. + +- Changed Clipboard.c to fix invalid read errors in nxagentGetClip- + boardWindow() function. + +- Implemented FR11C01218. Modified Font.c introducing the new function + nxagentLoadQueryFont, this function loads the font_struct struct + locally instead of sending a QueryFont request. + +- Modified nxagentListRemoteFontsfunction to fill nxagentFontList + struct with all remote fonts, avoiding further calls to XListFonts. + +- Added two functions, nxagentFreeRemoteFontList and nxagentFreeFont, + used in disconnect phase to empty the nxagentFontList struct and + the cached FontStruct elements, respectively. + +nxagent-2.0.0-21 + +- Updated to include the remote proxy version in the NXGetControl- + Parameter reply. + +- Updated to use the NXDisplayFlush() and NXSetDisplayPolicy() int- + erfaces. + +nxagent-2.0.0-20 + +- NXInitDisplay() and NXResetDisplay() are called at the time we + open or close the display, to let nxcompext set up its internal + structures. + +nxagent-2.0.0-19 + +- Activated the streaming of the images even in the case of a link + type LAN. + +- In NXmiexpose.c, if the number of rectangles in an exposed region + exceeds 4, we let a predicate function decide if it is better to + send the window extents, rather than the rectangles in the region. + +- Added the NXAGENT_SERVER define in the Imakefile. It will be used + in future to mark all the modifications made to files we imported + from other layers. + +- Removed the warnings from NXmiexpose.c. + +nxagent-2.0.0-18 + +- Imported NXmiexpose.c in the agent code. + +- Removed NXmiwindow.c from the agent code. We now use the original + miwindow.c + +- Removed the static qualifier from the _NXFontPath definition. + +- Started implementing the new lazy encoding mechanism. For each of + the drawables, the agent will create a "corrupted" region and will + try to synchronize the drawable when there is bandwidth available. + This is a work in progress. + +- Implemented the function nxagentFbOnShadowDisplay. This is a test + facility which opens a window on the display showing the content + of the agent's framebuffer. + +nxagent-2.0.0-17 + +- The image streaming procedure is now activated also when using a + link of type LAN. + +- Removed the call to NXTransDestroy() in nxagentCloseDisplay. The + NX transport is now implicitly shut down by either NXForceDisplay- + Error() or XCloseDisplay(). + +- Updated to comply with the new NX function prototypes introduced + in nxcomp-2.0.0-31. + +nxagent-2.0.0-16 + +- Fixed a bug in the nxagentModifyPixmapHeader function that was + causing some glyphs to be displayed incorrectly. + +- Implemented the test function nxagentPixmapOnShadowDisplay, useful + to display a pixmap on the real screen to check its consistency. + +nxagent-2.0.0-15 + +- Ensured that, before restarting a client after a no-split, all the + pending image commits are executed. + +- Installed the display error predicate function before trying to + open the display even at session startup. This prevents the agent + from disappearing silently if a failure occurs before the display + initialization is completed. + +- Moved the initialization of the callback functions in Display.c. + +- Added some interfaces to manipulate the callbacks and the error + handlers and verify the state of the display flags. + +nxagent-2.0.0-14 + +- Implemented stub versions of the nxagentDisplayCongestionHandler() + and nxagentDisplayBlockHandler() callbacks. See nx-X11-2.0.0-17. + +- Added the nxagentDisplayErrorPredicate() function. In combination + with changes implemented in nx-X11-2.0.0-16, this allows the agent + to abort a blocking operation and shutdown the display in a timely + fashion if a signal or any other error condition is received insi- + de Xlib. + +- Modified nxagentWaitSplitEvent() to use XIfEvent() as we can trust + the proxy to either send the event or give up the proxy connection. + The function will also give up when an error condition is raised, + like for example a session termination requested by the user. + +- Removed any remaining reference to the unused display buffer and + image cleanup functions. + +- Fixed exposures problems when reconnecting. + +- Solved TR05C00896. The problem was due to window manager utilizing + zero-thick-lines drawing requests. These drawing operations are now + performed by calling fbPolySegment() instead of miPolySegment(), + which doesn't handle the zero-thick-lines drawing case. + +nxagent-2.0.0-13 + +- Improved the management of the expose events. We now create the + fake window used to keep the agent synchronized with the X server + only once, instead of creating and configuring a different window + for each generated region. + +- A warning is printed if the changes requested for the fake window + don't match the changes reported in the subsequent ConfigureNotify + event. + +- Imported previous changes in NXevents.c into the 3.0.0 port. + +nxagent-2.0.0-12 + +- Activated the image streaming also during the reconnection. This + makes possible to leverage the remote disk cache. + +- Ensured that all clients are restarted when the session is suspen- + ded. This is required because the proxy is gone but we may have + some client still waiting for the completion of a split procedure. + +- Skipped the reset of the keyboard device if the display breaks at + the time it is being reconnected. + +- As the reset of the keyboard may have failed before we were able + to set a valid DeviceIntPtr, also added a check in ProcessPointer- + Event(), in NXevents.c to verify that the state of the display is + valid before accessing any of the device members. This is to be + better investigated. + +nxagent-2.0.0-11 + +- Solved TR02D01298. The clip region associated to the current glyph + was not updated because the serial number of the virtual pixmap + pointed by the picture was not incremented. + +- Imported the NXmiglyph.c file from render directory. + +- Removed the patch added in the release 1.3.2-6 temporary fixing this + problem. + +nxagent-2.0.0-10 + +- Various improvements the wakeup procedures. + +- Implemented the FR10C01110. Now, the X11 agent manages both the + PRIMARY and CLIPBOARD selections. It is possible copy and paste text + also by using Ctrl+C and Ctrl-V. + +- Modified NXdispatch.c in order to correctly include header files. + +- More cosmetic changes and code cleanup. + +- Imported changes into the files for the 3.0.0 port. + +nxagent-2.0.0-9 + +- Rewritten the procedures suspending and resuming the clients in + Control.c. This solves a problem with clients that were restarted + at wrong time and should ensure that multiple events for the same + client are correctly handled. + +- Removed the calls to NXSetUnpackGeometry() setting the parameters + for the client 0. The geometry is now set only at the right time, + just before trying to unpack the image. + +- Removed the sample code using the NXTransChannel() interface. + +nxagent-2.0.0-8 + +- Added test code showing how to open a new NX channel by using the + NXTransChannel() interface. + +- Streaming of images is not attempted in the case of link LAN. + +- Added preliminary code to the tell the proxy to flush the link if + the agent is idle. + +- Imported changes from nx-X11-2.0.0-14 in NXdixfonts.c. + +nxagent-2.0.0-7 + +- Modified exposures managing: agent synchronizes both with remote X + server and remote window manager for every generated region. Synch- + ronization is reached sending a ConfigureWindow request for a fake + window created on purpose. This way the exposures for the resulting + region coming from calculating the difference between local region + and the remote region are sent to clients in order to avoid duplica- + ted refreshes. + +- Improved new algorithm for managing exposures in order to work pro- + perly also in rootless mode: added privates to windows in order to + get information about mapping of windows on remote X server and vi- + sibility state too. This way local exposures are replaced by remote + ones if windows are mapped only for agent or windows are not fully + visible. This solves TR08C00971. + +- Window attributes values about backing store and save-under are re- + spectively set to NotUseful and False when creating a window on re- + mote X server and ignored when a client requests to change these + attributes. + +- Removed a no more needed function call to generate exposures when + resizing windows. + +nxagent-2.0.0-6 + +- Updated the NoMachine copyright notices. + +nxagent-2.0.0-5 + +- Added handling of font reconnection failure. In case of failure in + reconnecting some font, the agent adds the font server connection + forwarded by nxcomp to the font path of the X server. + +- Fixed TR09C01022. Moved the handling of the session states into + main cycle. The session states are not more handled into SIGHUP and + IOError handlers but into nxagentHandleConnectionStates() called in + nxagentWakeupHandler(). + +- In ResizeChildrenWinSize(), privates storing window geometry are + updated even if the call to PositionWindow() is skipped. This have + to be done because the window is moved by the X server accordingly + with window gravity. This prevent some window positioning error on + the real display evidenced with OpenOffice and GNOME. + +nxagent-2.0.0-4 + +- Solved TR12C01234. In some conditions Alt-F4 keystroke made the user + unable to open the Gnome Menu panel. This was due to the agent dis- + carding KeyRelease events for Alt-F4 and Alt-F2. + +- Undefined TEST and DEBUG in Dialog.c + +- Changed the NXAGENT_VERSION define from 1.5.0 to 2.0.0 + +- Caching and streaming of images is now disabled when dispatching + requests from the GLX and XVideo extensions. + +- Added the NXxvdisp.c and NXglxext.c files. These files are needed + to intercept calls to the XVideo and GLX extensions. Only files + in the main directory are imported. Files in the X directory, used + for the 3.0.0 port, for now are empty. + +- Added the nxagentXvTrap and nxagentGlxTrap flags. These flags are + set when dispatching requests from the XVideo and GLX extensions. + +- Added the GL and Xext include directories to the Imakefile to be + able to compile the NXxvdisp.c and NXglxext.c sources. + +- Modified the NXrender.c and NXshm.c files to set the nxagentGCTrap + nxagentRenderTrap and nxagentShmTrap even when dispatching requests + from swapped clients. Files for the 3.0.0 port are not updated. + +nxagent-2.0.0-3 + +- Solved a problem in the export of WM_SIZE_HINTS properties in root- + less mode on 64 bit machines. + +- Modified Render.c in order to correctly process Xrender header fi- + les on 64 bit machines. + +- Made changes in order to compile the agent in the Cygwin environ- + ment. + +- Renamed the files Time.* to Millis.* + +- Specified the relative path of some included header files. + +- In the Imakefile added a new include paths order related to the + Cygwin environment to avoid name clashes. + +- Disabled the MIT-SHM extension in the Cygwin environment. + +- Fixed TR11C01186. Added -timeout item to the usage message. + +- Fixed TR08C00945. Scrolling a document in Firefox caused image left- + overs with animated banners. Set the right window gravity on windows + created in the real X server. Let X move children for us accordingly + with window gravity attribute, without dix interferences. + +- Removed logs related to parsing of the options file. + +- Modified dialogs in order to show the name of the session in the + caption. + +nxagent-2.0.0-2 + +- Imported changes up to nxagent-1.5.0-112. + +- Fixed TR12C01241. The failure condition returned by the XQueryTree + function is managed in order to avoid the subsequent errors. + +- Fixed the TR11C01165. X11 sessions could not be started on Ubuntu + 5.10 because of the different location of fonts. Now we check the + existence of the fonts directory pointed by the default XF86 and + X.org font path and, if the directory does not exist, we use the + alternate font path used on Ubuntu. + +- Set the default value of DeviceControl option to False before resu- + ming a session. + +- Added a warning message printed if reset of keyboard fails at recon- + nection. + +- Fixed TR11C01185. Solved by checking if there are windows iconized + when a window is destroyed. + +- Fixed TR11C01164. The xkbcomp process used LD_LIBRARY_PATH as it was + a child of the agent. Added a call to NXUnsetLibraryPath() in Init.c + in order to remove LD_LIBRARY_PATH before executing a child process. + +- Check if there are windows iconized before terminating a rootless + session. + +- Modified CHANGELOG to include reference to fixed TRs TR08C00967 and + TR08C00969. Removed some typo. + +- Fixed TR11C01194. The agent crashed if launched with -kb option. + +- Fixed TR10C01042. The keyboard didn't work if the session migrated + from Apple X server to another platform and viceversa. This has been + solved by initializing the keyboard device whenever the session is + resumed. This feature can be disabled by the new option -nokbreset. + +- Fixed some compilation error arising if TEST was enabled in the file + Keyboard.c. + +- Fixed TR11C01167. During the disconnection the font structures poin- + ted by the font cache were freed leaving inconsistent data in the + corresponding privates. Now they are nullified and the GCs are che- + cked to guarantee a correct font handling in the suspended state. + +nxagent-2.0.0-1 + +- Opened the 2.0.0 branch based on the 1.6.0-11. + +nxagent-1.6.0-11 + +- Updated the NX.original copies of files in X directory. + +- Merged the NX changes: + + - From dix/extension.c to NXextension.c. + - From dix/dixfonts.c to NXdixfonts.c. + - From dix/glyphcurs.c to NXglyphcurs.c. + +- Export of CARDINAL properties are expanded to 64 bit units on 64 + bit machines. + +- Solved a segmentation fault when handling configure notify events + in rootless mode on 64 bit machines. + +- Merged the NX changes from dix/property in X/NXproperty.c. + +- Correctly allocated the local variable used in the call to NXGet- + CollectedInputFocus to be of 64 bit on 64 bit machine. + +- Defined symbolic constants XlibWindow in order to propertly handle + export property on 64 bit machine. + +- Moved the XlibAtom define from Atoms.h to Agent.h. + +- Modified export properties of type Window and Atom in order to han- + dle correctly Window and Atom types on 64 bit machines. + +- Removed some invalid read in Atom handling code when compiled for 64 + bit, due to mismatched size of Atom type between Xlib and Xserver + code. + +- Modified some header files in order to properly see the correct pro- + totypes of some Xlib structures on 64 bit machines. + +- The variable currentDispatch is always defined. + +- The dispatch current time is updated, this way the initial timeout + can elapse and the splash window is removed. + +nxagent-1.6.0-10 + +- Imported changes from nxagent-1.5.0-103. + +- Removed some redundant redeclarations. + +- Merged the NX changes from randr/randr.c to NXrandr.c. + +- Removed some warnings in NXrandr.c. + +- Removed NXAGENT_FORCEBACK and NXAGENT_INTERNALBS code. + +- Added ddxInitGlobals function in order to compile with the new X.org + tree. + +- Converted nxagentSynchronizeShmPixmap from macro to function to + solve a graphical render problem caused by the variable's scope. + +nxagent-1.6.0-9 + +- Imported changes from nxagent-1.5.0-102 + +- Fixed TR10C01124. Function nxagentSetPictureFilter() filled the log + with a debug message. + +- Removed a debug message in Events.c. + +- Run function nxagentSetTopLevelEventMask() only in rootless mode. + +- In the Java application IntelliJ the dropdown menus was shown in a + wrong position when the main window was moved or minimized. The + problem is solved for KDE desktop environment. + +- Fixed TR08C00967, TR08C00969, TR08C00941. Our incomplete implementa- + tion of the MIT-SHM X11 extension was a problem for some applica- + tions using the Shared Memory Pixmaps. Now the extension support has + been completed, so the nxagent can handle the Shared Memory Pixmaps + requests. Introduced some changes in the render implementation to + synchronize the content of the Shared Memory Pixmaps with the X ser- + ver before performing the ChangePicture and Composite operations. + +nxagent-1.6.0-8 + +- Fixed TR09C01028. The problem was the GC foreground was not updated + on the X server. This was due to the private fields was not copied + from a GC to another in the function nxagentCopyGC(). Added macro + nxagentCopyGCPriv in GC.h. + +- Solved TR11C01162. Removed the dialog shown by nxcomp/nxagent when + the resume of a session is happening over a slow link. + +nxagent-1.6.0-7 + +- Imported changes up to nxagent-1.5.0-100. + +- Fixed some compilation errors. + +- Fixed a typo in nxagentChangeClip() declaration. + +- Fixed TR10C01040. After the session resume the applications using + OpenGL were not correctly resumed because some GCs were not recon- + nected. Now we save these GCs in a safe vector, so we can't lose + them. + +- Improved font reconnection procedure in order to take advantage of + new font channel provided by nxcomp. If resuming session fails be- + cause missing fonts, the font channel provided by nxcomp is added + to font paths of X server. After reconnection succeded the font + channel is removed from font paths. + +- In the Java application IntelliJ the dropdown menus remained opened + and shown in a wrong position when the main window was moved or + minimized. This problem has been solved by sending a sinthetic event + to client. This solves partially TR09C01012. + +- In the same application the caret was not shown in the text window. + Solved the problem by setting nxagentGCTrap before calling a MI + function in every GC operations. + +- Merged the NX changes: + + - From render/glyph.c to NXglyph.c. + - From Xext/shm.c to NXshm.c. + - From render/render.c to NXrender.c. + - From mi/miwindow.c to NXmiwindow.c + - From render/glyphstr.h to NXglyphstr.h. + - From render/picturestr.h to NXpicturestr.h. + - From render/picture.c to NXpicture.c. + - From dix/dispatch.c to NXdispatch.c. + - From dix/events.c to NXevents.c. + +- Changed picturestr.h glyphstr.h to remove some formatting changes + compared to the original files. + +- Disabled Xinerama extension in order to fix a type conflict in NX- + dispatch.c. + +- The current directory has been moved in front of the include dire- + ctory list. + +- Removed NXAGENT_FORCEBACK code in files imported from DIX. + +- Changed NXshm.c NXrandr.c NXproperty.c NXpicture.c NXglyphcurs.c + NXglyph.c NXextension.c NXrender.c NXdixfonts.c NXdispatch.c NXmi- + window.c to remove some formatting changes compared to the original + files. + +- Added copyright notice to file NXrandr.c. + +- All files, except those from mi and dix, compile fine in the new + tree. Problems remain with different size of Atoms and other XID + objects. + +- More compilation fixes for the new tree. + +- Merged the NX changes from dix/window.c to NXwindow.c. + +- Changed NXwindow.c and NXevents.c to remove some formatting chan- + ges compared to the original files. + +- More compilation fixes aimed at porting the agent to the new tree. + +- Started porting the agent to the 6.8.99.16 X.org tree. + +- Lot of compilation fixes aimed at building in the new environment. + +- Files imported from the X.org tree's dix and mi will have to be + recreated in the nxagent/X directory. The new files will be inclu- + ded and built from the nxagent/X director if the NXAGENT_UPGRADE + symbol is defined (as it is the case when building in the 2.0.0 + nx-X11 tree), otherwise the usual NX* files in the nxagent's dir- + ectory will be compiled. + +- Fixed TR09C01021. SIGHUP it was not received from the proxy. The + handler of SIGHUP must be installed also in the case of not persi- + stent sessions. + +- In non persistent case: if session is normally running, SIGHUP sig- + nal is dealt like SIGTERM, otherwise it is passed to the proxy. + +- Fixed TR09C01027. Changed function nxagentHandleConfigureNotify() + in order to get changes of the staking order in a rootless session + even if no window manager is running. + +- Fixed TR09C01025. The problem was XView application could be unable + to respond to user's input. Modified the Event Mask for non top le- + vel windows reparented by the root window. Set the input member of + XWMHints to communicate the window manager the keyboard focus model + used by the application. + +- Fixed TR09C01026. Added 'fast' and 'slow' to the set of accepted + command line parameters. 'fast', 'slow' and 'geometry' command line + parameters have precedence regarding the options file. + +- Fixed TR08C00968. There was a problem in the implementation of the + render extension. + +- Fixed TR09C01016. In rootless mode when the session was resumed, + the cursor was shown with a wrong shape. + +- Fixed TR09C01011. Allowed clients to monitor the root window for + structure redirect, button press and resize redirect events in root- + less mode. This is a quick hack to make the java bean shell work + flawlessy with the agent. + +- Solved TR08C00961. Improved the algorithm updating the sprite win- + dow. Now it is updated based upon crossing and motion event. Since + on some X server, like Windows and MacOsX X servers, the only cros- + sing event is not a reliable method to trace the sprite window chan- + ges. + +- Fixed TR08C00966. Solved the problem on Windows when a rootless + session is suspended and some of the application windows are + minimized. + +- Fixed TR08C00960. Updated the internal screen dimension in rootless + sessions at reconnection. + +- Fixed TR09C01005. The problem was that the 'render' option on the + command line was overridden by the one provided in the options file. + +- Implemented the HandleEmptySplitEvent function that synchronizes all + the drawables after the depletion of the split store, when the lazy + option is activated. + +- Some changes in order to avoid duplicated refreshes when display- + ing Mandrake's kde menu. + +- Changed level of some logs from WARNING into TEST in Window.c and + in Rootless.c. + +- Fixed TR08C00958. Changed the log message printed when the user re- + quest to resume the session. + +nxagent-1.6.0-6 + +- When reconnecting, try to estimate the shift on the main window due + to WM reparenting. + +- In the handling of configure events, if a WM is running save the po- + sition of the main window only if event is synthetic. + +nxagent-1.6.0-5 + +- Command line option -noshmem disables shared memory extension in the + agent. + +- Changed level of some logs from WARNING into TEST. + +nxagent-1.6.0-4 + +- Some changes in order to improve handling of expose events in root- + less. The GetInputFocus request is not sent after reconfiguring a + top level window: window manager intervention could give race condi- + tions. The request is placed in WindowsRestructured() in order to be + sure it is sent after any event that could generate expose. + +- Zero lenght change property are now imported in rootless mode. + +- Corrected few typos. + +- Replaced the function usleep with NXTransContinue when NX transport + is running. + +- Changed the session state to GOING_DOWN as soon as the reconnection + is failed. + +nxagent-1.6.0-3 + +- Updated rootless toplevel window map when a window is reparented to + the root window. + +- Renoved duplicated entry in rootless toplevel window map. + +nxagent-1.6.0-2 + +- Removed TEST and DEBUG in Color.c. + +- Removed a compilation error in Atoms.c if DEBUG is enabled. + +- Removed invalid read at server reset in rootless mode, now the a- + toms description are duplicate before that we cache them. + +- Now the local atom in the atom cache are reset when exiting from + the dispatch loop. + +nxagent-1.6.0-1 + +- Opened the 1.6.0 branch based on nxagent-1.5.0-87. + +nxagent-1.5.0-87 + +- Corrected the enable-disable lazy encoding dialog in order to show + the correct keystroke Ctrl-Alt-E. + +nxagent-1.5.0-86 + +- Reset agent position at reconnection when the new size of display + doesn't match the old size and fullscreen is on. + +- Inserted a comment about handling of expose events. + +nxagent-1.5.0-85 + +- If fullscreen and resize options are true when reconnecting, geo- + metry option is ignored and the root window is resized to the en- + tire screen. + +- Read the position of the main window at startup from geometry op- + tions. + +nxagent-1.5.0-84 + +- Changed the keystroke Ctrl-Alt-L to toggle the image encoding on + and off to the new combination Ctrl-Alt-E. + +- Enabled the keystroke Ctrl-Alt-M to minimize the root window also + in window mode. + +nxagent-1.5.0-83 + +- Replaced the call to XIfEvent() with something less efficient but + safer, based on XCheckIfEvent(). The previous version might never + return if an I/O Error was encountered waiting for the event. The + new version fails gracefully, and returns after having restarted + the client. + +nxagent-1.5.0-82 + +- Removed some debug logs. + +nxagent-1.5.0-81 + +- Forced window mode if X server geometry has changed at reconnection. + +nxagent-1.5.0-80 + +- Reset resize desktop at startup flag before reconnection. + +nxagent-1.5.0-79 + +- Removed race condition in the parsing order of the options parame- + ter, now the geometry parameters are set in screen initialization. + +nxagent-1.5.0-78 + +- Disabled auto-resize and viewport mode dialog in case of rootless + session. + +- Removed no more used -backingstore option from usage messages. + +- Modified -bs command line option: now the default value "when_re- + quested" is always set. + +- Fixed wrong size of root window when switching from full screen to + window mode and viewport navigation mode is enabled. + +- Added option that solved a minimize bug in LeaveNotify when the + root window is in full screen and the user is using viewport navi- + gation mode. + +- Forwarded HUP signal to NX transport, when session state is up and + running. + +nxagent-1.5.0-77 + +- Do PutImage in every case. Don't check if the drawable is synchro- + nized. + +- Do CopyArea, CopyPlane, Composite in every case, don't check whether + the source is dirty. + +nxagent-1.5.0-76 + +- Terminate rootless session 15 seconds after the last mapped window + has been destroyed. + +nxagent-1.5.0-75 + +- Ctrl-Alt-T shows suspend/terminate dialog also in rootless mode. + +- Sleeps 50 ms in the block handler if the session state is down. + +- In rootless mode, the focus window is changed following FocusIn + events received from the real X server, also in the case no win- + dow manager has been detected. + +nxagent-1.5.0-74 + +- Changed the alerts names to comply with nxcomp-1.5.0-57. + +- Moved loading of placeholder from startup to the first time it is + needed. + +- Corrected a typo in the CHANGELOG. + +nxagent-1.5.0-73 + +- Ignored put image on not synchronized drawables, when the image + doesn't cover the entire surface. + +- Added parsing of render parameter in option file. + +- Ignored I/O Error when session is suspended. + +- Managed I/O Error at reconnection. + +nxagent-1.5.0-72 + +- Fixed offset of the default window at reconnection and after switch- + ing from fullscreen in window mode. + +- Suppressed the -lazy command line option. + +- Made some slightly changes in GCOps.c and Pixmap.c in order to com- + ply with the new 'Lazy' option. + +- Avoided to do CopyArea, CopyPlane and Composite operations when the + source drawable is dirty. + +- Rootless disconnect dialog has changed. This dialog is launched + after some time the last window has been closed. + +- Ignored geometry changes at reconnection if resize at startup is + not set. + +- Removed reset of the offset of the root window in viewport mode at + reconnection. + +- Fixed some refreshes problems in viewport mode and in desktop resize + mode. + +- Fixed a memory leak in nxagentWindowExposures(). + +- Added predicate to nxagentDispatchEvents. + +- Implemented framework in order to wait for a free resource entry, + when calling the asynchronous Collect* functions. + +nxagent-1.5.0-71 + +- Added keystroke Ctrl+Alt+L switching lazy encoding option. + +- Disabled viewport movement in resize mode. + +- Changed agent geometry at screen resize. + +- Changed agent geometry at initialization. + +nxagent-1.5.0-70 + +- Restored the set of blocked signal after the dialog pid just laun- + ched has been stored. + +- Removed an already fixed FIXME. + +- Updated the copyright message. + +nxagent-1.5.0-69 + +- Started working at the integration of the lazy encoding functiona- + lity. Made the agent draw the placeholder if the image is split and + never suspend the client. There is no provision for synchronizing + the drawables yet. + +- Made the lazy encoding configurable by the new 'Lazy' option. + +- Updated to include the changes in the NXStartSplit() and NXCommit- + Split() requests. + +- This version requires nxcomp-1.5.0-55 and nxcompext-1.5.0-16. + +nxagent-1.5.0-68 + +- Fixed reconnection of iconified windows. + +- Ignored the X server's scratch pixmap at reconnection. + +- The desktop gets automatically resized at reconnection if the desk- + top resize option is enabled. + +- Added the resize option in nxagentProcessOptionsFile() to allow the + user to change the geometry of both the root and the default window + at reconnection. + +- Fixed max size of the default window at startup when auto-resize + mode is enabled or in the case of a reconnected session. + +- Made some minimal changes in Atoms.c and NXdispatch.c. + +nxagent-1.5.0-67 + +- Changed handling of expose events received from real X server. A re- + gion is composed from expose events by checking the count field. + +- Reimplemented the exposures managing. Now the GetInputFocus request + is sent after a window has been configured or unmapped. We use a + vector to store windows originating expose events while waiting for + the reply to GetInputFocus. + +nxagent-1.5.0-66 + +- Added the DisplayLatency value in the agent options. This is int- + ended to give a hint about the latency of the current display + connection. The value is currently used to determine if the agent + is running across a slow link, and so it's appropriate to display + the begin-reconnection alert. + +nxagent-1.5.0-65 + +- Added the DesktopResize option. It controls the behaviour of the + automatic (RandR) resize of the desktop when dragging the agent's + window border. + +- Automatic resize is again the default. + +- Disabled the test logs in Events.c, GCOps.c Pixmap.c, Handlers.c, + Reconnect.c. + +- More cosmetic changes and code cleanup. + +nxagent-1.5.0-64 + +- Rewritten the image streaming procedure to better leverage the new + infrastructure. The start-split/end-split procedure is always init- + iated by the agent, including when the size of the image is below + the threshold, but the client is only suspended when the split has + taken place in the NX transport. + +nxagent-1.5.0-63 + +- Updated image streaming to use the new NX notification events. + +- Removed the references to the NXSync() operation, not used anymore + by the agent. + +nxagent-1.5.0-62 + +- Fixed wrong position of the root window in case of viewport naviga- + tion mode. + +- Added a field to the client private to trace the client type. + +- Tracked which clients are nxclient dialogs in order to not run the + pulldown dialog on them. + +nxagent-1.5.0-61 + +- Disabled server reset if not needed by XDMCP. + +- Disabled persistence for indirect XDMCP session until the first gre- + eter with the list of host has disappeared. + +- Created a small data structure to contain information about integri- + ty status and placeholder status of a drawable. + +- Modified the call to nxagentRealizeOnePixmap function in order to + avoid errors during the signal handling. + +nxagent-1.5.0-60 + +- Added the XDMCP option. If both Rootless and XDMCP are selected the + session will fail. + +nxagent-1.5.0-59 + +- Limited the permission to reset the agent only to indirect XDMCP + sessions, only one reset is allowed. + +- Fixed max size of the default window when switching from fullscreen + to window mode and auto-resize is disabled. + +nxagent-1.5.0-58 + +- Enabled reset mechanism, in order to make XDMCP session work proper- + ly. + +- Added XSync for window manager detection, after a server reset since + the XInternAtom already used should be cached. + +- Now the pixmap status is always tested on real pixmap. + +- The placeholder is drawn only once per drawable. + +- Implemented nxagentUnmapWindows() in case of failed reconnection if + the session was running in fullscreen mode and NX transport is not + enabled. + +- In nxagentPutSplitImage(), passing leftPad to XCreateImage(). + +- This version avoids sending the XSync() to the remote when a large + amounts of GetInputFocus requests are issued by the same client. + It will require more testing, especially to verify how it works on + old Windows machines. + +- Changed the NXCommitSplit() call to comply with the new interface. + +- The drawable status is now propagated on graphic operations where + the source is using the tile and stipple components on the graphic + context and the tile or stipple are not synchronized. This affects + the following operations: + + - PolyLines + - PolySegment + - PolyRectangle + - PolyArc + - FillPolygon + - PolyFillRect + - PolyFillArc + - PolyText8 + - PolyText16 + +nxagent-1.5.0-57 + +- Removed two XSync() operations at screen initialization. + +- Modified keyboard initialization in order to load the correct rules. + This is choosen according to the vendor string of X-Window system in- + stalled on the local machine. + +- Corrected a few typos. + +- When the NX transport is present, the failed reconnection dialog is + launched on the remote X server by using the NXTransAlert() function. + The same dialog is managed by NXTransDialog() when a session is run + by connecting directly to the display. + +- Removed the function nxagentUnmapAllWindows(). + +nxagent-1.5.0-56 + +- Set the parent window for the pulldown dialog. + +nxagent-1.5.0-55 + +- Added an alert at the time the reconnection procedure begins. The + alert is shown only when the NX transport is present and the link + type is not LAN and is removed at the end of the resume operation. + +- Removed the former code used for testing the alert functionality. + +- Moved the function removing the splash window in Splash.c. + +nxagent-1.5.0-54 + +- Fixed initialization of window privates storing exposed regions. + This solves a bug affecting the refresh of windows introduced in + nxagent-1.5.0-42. + +- Added a STARTING state to nxagent. Until the agent is in this state + the suspension mechanism is not activated. + +nxagent-1.5.0-53 + +- Added the special keystroke Ctrl+Alt+R to enable or disable the + auto-resize mode. + +- A dialog notifies the user when the auto-resize mode is toggled. + +- Added a test alert at startup, to verify that NXTransAlert() is + working as expected. + +nxagent-1.5.0-52 + +- Changed the code to call NXTransDialog() and NXTransExit(). + +nxagent-1.5.0-51 + +- Solved a bug that prevented the clients that had been restarted + to be immediately selected for input. + +- Removed some code that was added for debugging. + +nxagent-1.5.0-50 + +- Fixed a memory leak in nxagentHandleExposeEvent(). + +- Fixed a memory leak in nxagentDestroyWindow(). + +- Now rootless dialog is launched only when last mapped window is + deleted, since we have pulldown window to control the session. + +- Added pulldown dialog to handle NX windows in rootless sessions. + This dialog is activated from a "magic" slice of window under the + top border. + +- Solved a problem with sessions that might fail at reconnection. + +- Now the message text of the dialog launched in case of failed re- + connection explains the reason why the agent cannot be resumed. + +- Implemented function nxagentUnmapAllWindows() to unmap all windows + if nxagent has failed to migrate the session to the new display. + +nxagent-1.5.0-49 + +- Fixed the problems with propagation of the drawable status. + +- Modified nxagentPutSplitImage in order to set the correct height + of the last split image. + +- Code cleaning and optimization in Dialog.c. + +- Solved bug that switched on the full screen state in rootless se- + ssion. + +- Changed the way dialog caption are set in rootless mode. It is set + upon the session name or session id value. + +- Corrected the function nxagentFailedReconnectinDialog(). + +nxagent-1.5.0-48 + +- Solved bug that switched on the full screen state in rootless se- + ssion. + +- Changed the way dialog caption are set in rootless mode. It is set + upon the session name or session id value. + +- Corrected the function nxagentFailedReconnectinDialog(). + +nxagent-1.5.0-47 + +- Now we call NXContinueOnDisplayError() with value 1 just after + having opened the display. This will cause the NX Xlib to return + in the case of an I/O error, instead of quitting the application. + +- Removed the references to Context.h and the related elements. + +- Reflected the changes occurred in NXlib.c regarding NXDisplayErr- + ror() and inverted the logic compared to NXDisplayIsValid(). + +- Added a dialog box to notify the user when nxagent has failed to + migrate the session to the new display. Because the main X agent + connection is unavailable, this dialog uses the auxiliary nxcomp + keyboard channel. + +- Disabled the special keystroke Ctrl+Alt+S if any dialog is already + running. + +- Started implementing lazy synchronization of pixmaps. At the pre- + sent moment the implementation doesn't try to perform any optimi- + zation on the windows' regions that have to be redrawn and neither + it checks the congestion state. After having synchronized a reaso- + nable number of pixmaps, it simply sends to all the affected win- + dows an expose event, mandating the repaint of the whole area. + +- Removed a warning in Atoms.c. + +nxagent-1.5.0-46 + +- Removed the longjmp() at the time an I/O error was encountered on + the display. + +nxagent-1.5.0-45 + +- Removed UNDEFINED status for drawables. + +- Now lazy encoding affects only windows. + +- Changed the block handler to call NXTransFlush() with 'if needed'. + +nxagent-1.5.0-44 + +- After reconnection, stored exposed regions are reset and the manag- + ing of duplicate expose events is restarted. + +- Detection of window manager has been moved to the start of screen + initialization. Screen dimensions and fullscreen option are over- + ridden if no window manager is detected. + +- Added a call to XSync() in switching fullscreen function in order + to synchronize it with the network behaviour. + +- Started adding provision for deferred writes in the NX transport. + When the flush policy will be set accordingly, X data accumulated + by the proxy will be written to the network under the control of + the block and wakeup handlers. + +- Fixed a bug in nxagentCopyArea(). In some cases, pixmap drawables + was erroneusly supposed to be windows. This produced invalid reads + when trying to access to fields of WindowRec structure. + +nxagent-1.5.0-43 + +- In the code managing the property notify events, NXCollectProperty + is not called if the window is not found in the tree mantained by + the agent. + +- Changed managing of screen resize in order to avoid repeated resize + of desktop. The agent sleeps one second, then all configure event + are read from the queue and the server connection. The desktop re- + size is performed after the last read configure event. + +- Changed nxagentImportProperty() in order to use NXCollectProperty + instead of XGetWindowProperty. This avoids many round-trips in root- + less mode. + +- Fixed Invalid write problem in nxagentRRSetScreenConfig(). + +nxagent-1.5.0-42 + +- Modyfied test of NXSetUnpackGeometry for visuals, so now the compa- + rison between visuals is based on their IDs and not on the memory + area allocated for their visual structure. + +- Modified exposure managing in order to avoid duplicated refreshes. + Now only exposed regions not formerly managed yet are sent to the + clients. + +nxagent-1.5.0-41 + +- Modified nxagentCloseScreen() in order to free the frame buffer. + +- Added information of the integrity of the windows. Now the integrity + has became a drawable property that will expand in every drawable to + drawable operation. + +nxagent-1.5.0-40 + +- Splitting of images now happens only if the display is a valid con- + nection. + +- The isItTimeToYield flag is now set in the dispatcher only when the + client has been actually suspended because of a karma, a sync, or + a split operation. + +nxagent-1.5.0-39 + +- Improved the handling of the PutImage request to offer provision + for splitting images coming from orders generated by extensions. + +- Fixed a problem with clients being unexpectedly restarted instead + of waiting for the end of split. + +nxagent-1.5.0-38 + +- Added a persistent dialog when agent is running in rootless mode. + +- Modified the policy of management of nxclient dialogs. + +- Fixed memory leak problem in nxagentPutSplitImage(). + +- Modified printing of some debug messages to avoid passing a null + pointer to fprintf(). + +nxagent-1.5.0-37 + +- Implemented initial support for streaming the packed images in the + handling of the MIT-SHM extension. + +nxagent-1.5.0-36 + +- Updated the pixmap status when a placeholder is copied on the pix- + map and when the pixmap is the target of a RENDER composite opera- + tion. + +- Solved the TR05C00900. The NX transport was forced to be set when- + ever the display name contained the nx prefix. + +- Implemented the FRSA052393. Removed the compression filters applied + by nxagent to cursor pixmaps. + +- Modified RANDR implementation to make the user able to resize the + desktop by simply dragging the agent window's border. Screen resize + is made after a small timeout, to give time to the last configure + event to come from the server and avoid multiple re-configurations + of the screen. + +nxagent-1.5.0-35 + +- Added the current screen size to the set of sizes returned by the + RANDR extension. + +nxagent-1.5.0-34 + +- Corrected the placeholder xpm image. + +- Added a client dialog to notify the user that nxagent is running in + fast or in slow mode after pressing Ctrl + Alt + S. + +- Modified RANDR implementation to give a set of screen sizes. Im- + plemented functions actually performing screen resize on a RANDR + request. Now toggling to fullscreen make the desktop cover the en- + tire screen area. + +nxagent-1.5.0-33 + +- Added an auto-disconnect feature similar to the one present in the + Windows Terminal Server. The feature is modeled on the built-in X + server's screen-saver. If the agent doesn't receive any input from + the user in a given timeout, it will either terminate the session, + if no client is connected to the display, or will suspend it, so + that applications will be left running. + +- The default is to disable the auto-disconnect option. The feature + is activated by specifying a "-timeout s" parameter on the command + line, with s being the timeout in seconds. The minimum allowed ti- + meout is 60 seconds. + +- The waitpid() call now only checks the agent's own children. + +- Moved the longjmp() context declaration to a new Context.h file to + avoid clash with redefinitions by the PNG headers. + +- Few other cosmetic changes. + +nxagent-1.5.0-32 + +- Added a check on the type of the connection to avoid cleaning the + images when not needed. + +nxagent-1.5.0-31 + +- Modified the placeholder frames, now it has a left top black border + and a bottom right grey one. + +- Modified fbShmPutImage() in order to set the correct size for the + temporary pixmap. + +- Modified nxagentForceExposure() and nxagentHandleExposeEvent() in + order to clip exposed regions to the window size region of the root + window. + +- Added a new placeholder xpm image. + +- Corrected few typos. + +- Added function to synchronize GC tiles and stipples whenever those + pixmaps have been realized. + +nxagent-1.5.0-30 + +- Hidden viewport windows to clients in QueryTree request in order + to make work XDMCP properly. + +nxagent-1.5.0-29 + +- Removed some warnings with gcc 3.4. + +- Added desktop -D switch to usage. + +- Paint window background draw on framebuffer only with OpenOffice + client. + +- Now fast copy are and fast getimage are no more set according to + the link type, their default value has been set to true. + +nxagent-1.5.0-28 + +- Modified nxagentUpdateViewportFrame() in order to solve a refresh + problem. Windows composing the external frame must be always on top + to be sure that agent sends expose events for every window. + +- In rootless mode agent doesn't export anymore the properties when + disconnected from the X server. + +- Changed the way agent check if the connection with the X server + is available. Instead of using a state machine it uses the display + flag. + +- Removed the SIGTERM handling function in persistent code. We don't + need anymore those function since agent is no more sleeping when + disconnected. + +- Implemented nxagentFreePropertyList() function in order to empty the + list of exported properties when the rootless agent is disconnected. + +- Added special keystroke Ctrl + Alt + S toggling between fast and + slow mode for GetImage and CopyArea. + +- Added missing handling of down arrow key in Keystroke.c. + +- Modified nxagentForceExposure() in order to intersect exposed re- + gions with the clip region of the root window. This prevents window + functions from painting outside the frame buffer. + +- Added the field usesFrameBuffer in struct nxagentPrivClient. Modifi- + ed GC funtion and DoGetImage() in order to write in the frame buffer + only if usesFrameBuffer is True. + +- Removed code performing PutImage in the frame buffer, as it is use- + less at the moment. + +- Modified ProcChangeProperty() to check WM_NAME property. + +- Added a piece of code in nxagentOpenScreen() checking for and remo- + ving duplicated visuals. + +- Added the Dialog.c Dialog.h files. Unified all calls to NXDialog, + and blocked SIGCHLD before calling in order not to get the signal + before the child pid has been stored. + +- Modified the algorithm that disconnect the running session in + order to avoid the opening of a new dialog box for closing or + suspending the nxagent. + +nxagent-1.5.0-27 + +- Changed the disconnect/reconnect procedure in order to have a pro- + per default colormap vector when session is suspended, solving a + segmentation fault in create window function. + +- Corrected few errors in slow copy area mechanism. + +- Modified screen initialization in order to allocate memory for the + internal frame buffer. + +- Modified some GC functions for writing to and reading from the frame + buffer. + +- Modified nxagentCreateWindow() for initializing the window in the + frame buffer. + +- Modified nxagentCreateColormap() in order to use the default visual + if a matching one is not found. + +- Modified function DoGetImage() in order to call nxagentGetImage() in + place of nxagentGetDefaultImage() if fast option is on. + +- Added nxagentCheckWindowIntegrity() function verifying the matching + between the internal frame buffer and the X server for a window. + +nxagent-1.5.0-26 + +- Added the property "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR" to the list + of exported property in rootless mode, in order to let clients use + the system tray. + +- Modified import of WM_STATE properties in rootless mode in order + to better handle null resources. + +- Enhanced the slow CopyArea mechanism in case of one part of the + image is out of the X server screen or out of nxagent screen. + +- Changed type for variables width and height of default window + from 'unsigned int' to 'int'. + +nxagent-1.5.0-25 + +- Added a new signal handler for SIGCHLD. The transport is set to + forward the signal (by means of a new NX_SIGNAL_FORWARD action). + This allows the agent to wait for its own children. + +nxagent-1.5.0-24 + +- Set up the RANDR extension. When querying the configuration, the + clients get 3 sizes, the first being the current size, the second + being the maximum size of the remote display, the third being the + minimum size (arbitrarily set to 100x100 pixels). Screen sizes in + millimeters are calculated based on the size reported for the real + display. + + An example of xrandr -q output is below: + + SZ: Pixels Physical Refresh + *0 800 x 600 ( 270mm x 203mm ) + 1 100 x 100 ( 33mm x 33mm ) + 2 1400 x 1050 ( 474mm x 356mm ) + Current rotation - normal + Current reflection - none + Rotations possible - normal + Reflections possible - none + + As you can note, reflections and rotation is not possible. + +- Set up the GLX extension. This provides basic support with GLX op- + erations being translated into core X protocol primitives. + +- Moved initialization of GLX and RANDR to the Extensions.c file. + +- Removed the references to the unused mfb library. Modified Screen.c + to allocate the right privates for the fb code. + +- Modified the Xserver Imakefile to link nxagent with FbPostFbLibs + and avoid including mfb/libmfb.a. + +nxagent-1.5.0-23 + +- Fixed an incorrect buffer length calculation when retrieving a re- + mote property. + +- Added a check to avoid the use of a NULL pointer when changing the + window cursor. + +- Implemented a function to lookup the remote pixmaps. + +- Changed the RENDER initialization messages. + +- Corrected a few typos in symbol names. + +nxagent-1.5.0-22 + +- Added the nxagentNeedConnectionChange() macro. + +- Small optimizations in the block and wakeup handlers. + +nxagent-1.5.0-21 + +- NXCollectGrabPointer() is called by passing nxagentDefaultClient(). + This is a macro that checks the validity of requestingClient and, + if the pointer is NULL, defaults to NXNumberOfConnections - 1. + +nxagent-1.5.0-20 + +- Replaced all calls to XGrabPointer with the asynchronous version + provided by nxcompext. + +- In DeactivatePointerGrab() function, mouse button state is set to + up if the window entered by the pointer is the root window and the + agent is in rootless mode. This change is needed because the sub- + sequent KeyRelease event could be not received by the agent (for + example if the focus had left the window), so that agent could be + unable to update the mouse button state. + +- In rootless mode, grabs exported to X in ActivatePointerGrab() are + always made asynchronous. The synchronous behaviour is implemented + by the agent, so that requiring a further synchronous grab down to + the real X server is of little use and potentially harmful. + +- Modified function XYToWindow() in order to manage the case that + mouse pointer is located on the title bar of a top level window in + rootless mode. + +- Reflected name changes to NXImageCache variables. + +nxagent-1.5.0-19 + +- Changed the implementation of the SIGHUP handler to forward the sig- + nal to the proxy only when appropriate. This allows nxagent to close + the NX connection without having to go through an I/O error on the + display. + +- Modified nxagentBreakXConnection() to check if the NX transport is + running and thus use NXTransDestroy(). Using a simple shutdown() may + not work, for example if NX is using the memory to memory transport. + +- Added the -D option, to let users specify that agent must be run in + desktop mode. This is presently the default. + +nxagent-1.5.0-18 + +- Set the PropertyChange mask on input/output window in rootless mode + in order to get the PropertyNotify events. + +nxagent-1.5.0-17 + +- Cleaned of the reconnection routines, removed the NXAGENT_RECONNECT + macro. + +- Now the SIGHUP handler forwards the signal also to the NX transport. + +- Moved the NXTransDestroy() call in the closure of the display, so + we can avoid going through the I/O error handler. + +- Removed an invalid free in the function that closes the display. + +- Commented out more code in Display.c to avoid the segfault on exit. + +- In rootless mode, now function XYToWindow() starts search from the + last window originated an EnterNotify event. In this way, we can + prevent shaded windows from getting mouse events. + +- The variable to disable the smart scheduler is set at its definition + instead of setting it in the Dispatch function. This avoids the call + to SmartScheduleInit. + +- Changed implementation of cursor visualization in rootless mode. We + made the cursor attributes changes go transparently to the X server + while in desktop mode we ignore any client request to change the cu- + rsor on the X side, and we just set the cursor on the default window + any time the pointer cross a window border. + +- Expanded the range of properties exported on the remote Xserver, + this way we export properties whose atom name starts with "WM_" and + "_NET_". + +- In Rootless mode PropertyChangeMask is added to top level window in + order to get PropertyNotify Events. + +- First implementation in rootless mode of nxagentImportProperty fun- + ction with which after reception of PropertyNotify Events, all chan- + ging properties coming from external clients such as Window Manager + will be imported in agent windows. + +- Changed the GetEventMask function in order to handle the InputOnly + windows that need to be notified of property changes in rootless + mode. + +nxagent-1.5.0-16 + +- Implemented the -B command line switch, to let nxagent impersonate + a "pure" proxy on the NX server side (that is without X connections + having to be managed by the nxagent's dispatcher). Such a "nxagent + -B" is going to replace the corresponding nxproxy process that in + previous version of NX server was run with the same options. + +- When running nxagent in 'bind' mode the X port where the the proxy + has to listen for connection must be specified after the -B option. + The other NX options must be passed in the DISPLAY environment. + + Example: + + nxagent -B :9 + +- The initialization procedure will check that the display included + on the command line matches the one specified in the NX display + options. + + For example, given the command: + + nxagent -B :9 + + The NX options must be something like: + + DISPLAY=nx/nx,link=modem:9 + + This allows users to find out which display the agent is impersona- + ting by running a 'ps' and inspecting the command line. + +- Fixed a bug preventing the proxy's ClientMessage to reach the right + function when activating rootless mode. + +- Removed unused function nomachineLogo. + +- Code cleaning and soem optimizations in Rootless.c. + +- We want to import all properties changed by external clients to our + internal windows. But we must ignore property notify generated by + our own requests. For this purpose we implement a list to record + every change property that we dispatch. This way when processing + a property notify we can distinguish between the notify generated + by our request and those generated by an 'outside client'. + +- In rootless mode, optimized window configurations mantaining inter- + nal stacking order. + +- Fixed focus troubles in rootless mode. Now focus window is set fol- + lowing FocusIn events. + +- In rootless mode, now fake KeyRelease events on FocusOut are sent + only if keys having down state are modifiers. This prevents from + sending key events to a wrong client. + +- Removed unused function nxagentRootlessNextSibling in Rootless.c. + +- Removed unused function nxagentRootlessStackingOrder in Rootless.c. + +- Fixed compilation error if TEST log is enabled in Events.c. + +- Changed Options variables to comply with NX naming rules. + +- Some additional cosmetic changes. + +nxagent-1.5.0-15 + +- Modified functions nxagentPutImage and DoGetImage for XYPixmap fo- + rmat. + +- Completed implementation of shared memory extension. + +- Implemented a mechanism that prevents monitoring of SubStructure- + Redirect ResizeRedirect and ButtonPress events by any clients simu- + lating the presence of a window manager running inside the agent. + +- Added debug functions in order to check the status of syncroniza- + tion between the pixmaps residing on the X server and the local + framebuffer ones. + +- Changed the policy used when realizing all the pixmaps in 'lazy en- + coding' mode so that the agent now switches to 'eager' policy. + +- Fixed the routine handling the pixmaps realization: pixmaps with + an invalid id are not processed anymore. + +- Solved a bug in the routine taking care of clearing the NoMachine + logo: the state of the background was set to 'pixel' without de- + stroying an eventual backround pixmap. + +- Solved a bug in the 'MakeRootTile' function: the value returned by + 'AddResource' was not interpreted in the correct way causing the + function to bail out without drawing the NoMachine logo and set- + ting the background state to Pixmap. + +- Renamed PlaceHolder.c to Lazy.c and PlaceHolder.h to Lazy.h. + +- Inserted a test feature that cleans the framebuffer pixmaps when + they are created. + +nxagent-1.5.0-14 + +- Changed some reconnection messages. + +- Now the disconnect procedure is called also after an IO Error is + received. + +- The rootless agent now doesn't filter anymore keystrokes combina- + tion related to desktop feature, like viewport navigation the full- + screen state and minimization. + +- In rootless mode, internal stacking order is updated by comparing + the stack of top level windows mantained by the X server with the + one mantained by the agent. A global configuration of windows is + performed from top to bottom through the stack. + +- In rootless mode, map state of top level windows is kept up to date + by managing map and unmap events. + +- In rootless mode, enter events are managed to keep track of top + level window position. It is very useful for managing differences + among window manager behaviours. It should be reimplemented follo- + wing the advice given in ICCCM 4.1.5. + +- In rootless mode, requests of configure top level windows are di- + rectly forwarded to the real X server. Internal configuration is up- + dated when configure events are managed by the agent. In order to + mantain internal stacking order up to date, a query tree request is + performed on the real root window. + +- Added viewport navigation by Ctrl + Alt + keypad arrows. + +- Fixed wrong internal configuration of agent top level windows, while + agent runs in rootless mode with metacity window manager. + +- Fixed segmentation fault in nxagent running in rootless mode with + OpenOffice. + +- Fixed wrong internal stacking order of drop down menus of firefox + with nxagent in rootless mode. + +nxagent-1.5.0-13 + +- Fixed compilation problem on solaris. + +- Modified the modify pixmap header function. Previously this function + has been modified in order to solve a glyph problem, enlarging both + the pixmaps dimensions by four. Corrected the misbehaviour that + modify the pixmaps dimension even if the caller doesn't want to + change it. + +nxagent-1.5.0-12 + +- Fixed erroneous behaviour of Root Window in fullscreen mode caused by + wrong value of XSpan and YSpan. + +- Fixed wrong clients' position at Reconnection in Rootless mode, + setting offset and WinGravity fields in XsizeHints structure. + +- Fixed segmentation fault on closing windows that stay always on top. + +- Moved the handling of configure notify events in the appropriate + functions, and cleaned it. + +- In rootless mode, internal stacking order of top level windows is + mantained up to date by monitoring events from window manager top + level windows. + +- Modify the creation of screen at reconnection for detecting an + eventual failure. + +- Removed export of window properties on the X server in desktop mode. + +- Changed the events mask for client's window set on the X server. + We don't use anymore the window mask choosen by clients. In rootless + mode for a top level window we use the default event mask and for a + child only the exposure mask. + +nxagent-1.5.0-11 + +- Restored default event mask at reconnection. + +- Fixed abnormal behaviour in rootless mode if application windows are + close to the lower and right bounds of the screen. This trouble was + due to the wrong size of the agent root window. + +- Fixed abnormal behaviour in rootless mode for mouse button events if + the application window is not fully contained in the screen. + +- In rootless mode, exposed region are extended a few to take in ac- + count border width offsets caused by window managers. + +- In rootless mode, grab pointer requests from clients are forwarded + to X server. This makes application able to close their pop up win- + dows on a pointer event. + +- Fixed wrong position of the agent root window after resize of main + window. + +- Changed the size of viewport frame windows in order to avoid re- + freshing problems. + +nxagent-1.5.0-10 + +- Handled the Client messages on rootless mode. + +- Initializations of event masks have been moved in a unique group of + functions. + +- Disabled the SmartScheduler in dispatcher as it seems to affect the + responsiveness of nxagent. + +- Modified the block and wakeup handlers. We could have left data to + write to our display connection when entering in WaitForSomething() + so we now flush everything before entering the select() and let the + proxy do all the buffering. + +- Fixed the wakeup handler to match the correct prototype. + +- Few cosmetic changes. + +- Inserted a test feature that cleans the framebuffer pixmaps when + they are created. + +- Adjusted pixmap status information in almost every gc operations. + +- Removed a warning for usleep not defined on Suse 9.0. + +- Adjusted pixmap status information in copy plane operations. + +- Throwed fatal error if on lazy encoding the place holder pixmap + couldn't be loaded. + +- Removed the static path to xpm file in place holder initialization. + +- Removed useless signal handler initialization multiple times. + +- Refined validation of atoms in the atom cache code. + +- Corrected few errors in atom cache initialization. + +- Added a primitive atom cache that mantain the map between internal + and external atoms. + +- Window properties export began on the X server side in rootless + mode, this way nxagent open the communication between local clients + and the window manager on the X server. + +nxagent-1.5.0-9 + +- Fixed wrong position of the main window in case of maximizing in + window mode. + +- Set the correct scan line lenght for XYPixmap created in PutImage + and GetImage. + +- Removed a segmentation fault in GetDefaultImage. The problem arose + because the XYPixmap created with a data storage taking in account + of only some planes instead of all the depths planes. Despite XPut- + Pixel was treating the image as a complete XYPixmap of that depth. + +- Removed MapWindow Error at reconnection caused by wrong value of + IconWindow. + +- Now nxagent_WM_START is intialized as soon as the Atoms are + queried. + +- Removed Geometry restrictions. + +- Changed the configuration of the agent window in window mode. + +- The agent window is correctly reconnected even if is resized. + +nxagent-1.5.0-8 + +- Updated copyright notices. + +- Removed a segmentation fault in font cache cleaning routine. The + problem arise when the session is disconnected and the font struct + are not allocated. + +- Used the return mask of XParseGeometry to correctly set only the + parameters that are involved. + +- Unified the initialization of all the geometry related parameters. + +- Updated the offset of the four viewport frames windows at recon- + nection. + +- Changed the way the geometry parameter is used. Now the first time a + session is started it set the internal dimension of the agent root + window, afterwards it only affects the dimension of the external + window on the X server. + +- Corrected splash screen offset at reconnection in fullscreen mode. + +- Agent can be launched in fullscreen mode and his geometry can differ + from the X server geometry. + +- Now Width and Height options are used to store geometry of the + default window even on fullscreen mode, and to restore the correct + dimension when switching back to window mode from fullscreen + we added two more options. + +- Removed an error in the move viewport procedure that didn't upgrade + the offset of the internal root window when the external root win- + dow was maximized. + +- Unified the initialization of all the geometry related parameters. + +- The window manager detection procedure is now started whenever there + is an attempt to minimize the fullscreen window or to pass to window + mode. + +- Function's optimization for detecting if WM is running. + +- Switching to window mode has been disabled when the window manager + is not running. + +nxagent-1.5.0-7 + +- Now background pixel is not reset at reconnection. + +- Now geometry is parsed also as a command line parameter. + +- Fixed wrong offset of the root window after a reconnection in case + of window mode. + +- Fixed wrong geometry of the nxagent window after a reconnection + in case of window mode. + +- Fixed wrong position of the main window after a reconnection in + case of fullscreen mode. + +- Fixed refreshing windows problems in viewport navigation. Four in- + visible windows are created around the agent window to automatica- + lly generate exposure when the viewport frame is moved or a windows + come out from the non visibile part of the agent window. + +- We need to store the GC records in a list that will be freed in case + the reconnection succed and will be restored in case of failure. We + have to do this because we cannot destroy the GC records in the + disconnect or reconnect procedure, because this way we couldn't + recover from a disconnection or a reconnection failure. + +- Rewritten the reconnection procedure. Since we cannot be sure + that the reconnection will succed we cannot destroy the display + structure, so we postpone the closing of the previous display + with the creation of the new connection. + +nxagent-1.5.0-6 + +- Adjusted usage list in order to show the R parameter for rootless + mode. + +- Added handling of display parameter to option file. + Corrected few typos error, in option file parsing. + +nxagent-1.5.0-5 + +- Removed error that prevented the realization of cursor in eager + mode. + +nxagent-1.5.0-4 + +- Fixed abnormal behaviour of termination dialog, after the keystroke + Ctrl + Alt + T. + +- Fixed segmentation fault in function parsing option file. + +- Fixed various errors on eager encodings. + +- Added lazy command line switch in order to switch lazy encoding + on. + +- Code cleaning. + +- Implemented a signal to switch between two pixmap + realization policies. + +- Corrected an error while defining pixmaps status. + +- Implemented a debug feature, consisting in a method that pushes + the synchronized realization of all the pixmaps. + +- Began implementation of place holders in replacing of images while + they are being loaded. + +- Performed some changes on spreading of pixmaps status information + on copy area. + +- Began implementation of lazy encoding. + +- Changed version to 1.5.0. + +nxagent-1.5.0-3 + +- Removed the option -nogetimage (FRSA052305). + +- Code cleaning in Font.c. + +- Removed NXAGENT_FONTMATCH macro. + +- Removed NXAGENT_FONTCACHE macro. + +- Handled the ReparentNotify event we get when in rootless mode + ours window are reparented from the window manager. Inserted + fake windows to take account of this new parents. + +- Removed the redirection of client message in rootless mode, and + the configuration of the WM_PROTOCOLS properties on all the top + level windows. + +- Removed parent ID from the windows private structure. + +- Implemented screen operation ReparentWindow. + +- Redirect all client message of type WM_PROTOCOLS and value WM_DELETE- + _WINDOW to internal clients in rootless mode. + +- Set the WM_PROTOCOLS property on all the top level window. + +nxagent-1.5.0-2 + +- Changed viewport navigation, in order to make it works in fullscreen + mode. + +- Changed special keystrokes used for closing session and minimizing + fullscreen window. + +- Removed the message 'NX was unable to negotiate a cache + for this session' (FRSA052296). + +- Fixed a minor bug. It made metacity produced a warning when the agent + started up. + +- Code cleaning. + +- Implemented dynamic handling of the main window's size in the X11 + agent (FRSA052264). + +- Implemented dynamic navigation of the main window's viewport in the + X11 agent (FRSA052265). Users can navigate the viewport while keys + Ctrl + Alt are pressed, either by arrows keys or dragging it by the + pointer. + +- Implemented dynamic handling of the full-screen attribute in the + X11 agent. + +- First implementation of dynamic handling of the full-screen + attribute (FRSA052263). + +- Now the X connection descriptor is not closed when disconnected, + because the transport layer still has reference to it. So we want + it busy till we don't close the display, so we shutdown it instead + of closing it. + +- Removed replys when disconnected. + +- Added the X connection number to the set of enabled input devices, at + reconnection. + +- Rewritten the disconnect/reconnect layout. + +- Now in the suspend status nxagent doesn't sleep. + +- Implementing toggle fullscreen special keys. + +nxagent-1.5.0-1 + +- Opened the 1.5.0 branch. + +nxagent-1.4.1-7 + +- Imported changes from nxagent-1.4.0-64 version. + +nxagent-1.4.1-6 + +- Implemented a GC cache for reconnecting pixmap. + +nxagent-1.4.1-5 + +- Handled the situation of disconnect when the pointer has been grabbed. + We disconnect and reconnect the "grabbing" cursor and after reconnection + we fake a button release in order to let client know that the pointer + button has in effect been released. + +- Code cleanup. + +nxagent-1.4.1-4 + +- Imported changes from nxagent-1.4.0-63 version. + +nxagent-1.4.1-3 + +- Imported changes from nxagent-1.4.0-62 version. + +nxagent-1.4.1-2 + +- Cleaned code in the GC reconnection area. + Scratchs GC are now reconnected before of the pixmaps. + +nxagent-1.4.1-1 + +- Opened the 1.4.1 branch. + +nxagent-1.4.0-65 + +- Cosmetic changes to the diagnostic output. + +nxagent-1.4.0-64 + +- Changed the RENDER version advertised to X clients to be the lowest + value between the version of RENDER of nxagent and of the remote X + server. + +- Disabled fast copy area and fast get image flags, if RENDER extension + is not available. + +- At the screen initialization, if we don't have window manager we + grab keyboard to let nxagent get keyboard events. + +- Completely rewritted the handling of KeyPress events, now we moved + all the test for 'special' keybindings in file keystroke.c. Added the + combination MOD1/2-CTRL-SHIFT-<TAB> for terminate/suspend the session, + we used the combination MOD1/2 in order to let it work even on MacOS + where Alt(MOD1) doesn't seem to be set. + +- Ignored visibility notify events on the icon windows, that were + messing up the agent visibility state. + +- Changed nxagent reaction on VisibilityNotify event. It fixed the + problem with refresh session under Mac OS X with NXDarwin. + +nxagent-1.4.0-63 + +- Reset the congestion state at transport initialization. + +nxagent-1.4.0-62 + +- Fixed the disconnection and reconnection of window that have attached + an animated cursor. + +nxagent-1.4.0-61 + +- Removed the XInputExtension initialization in order to use the more + general mi extension initialization enabled on new mi version. + +- Removed some useless test and logging info on copy area function. + +nxagent-1.4.0-60 + +- Changed the implementation of CopyArea and CopyPlane. + If both drawables are on framebuffer we send NoExpose to clients, + otherwise we use the mi function HandleExposure to calculate the + region to be exposed instead of let mi redo all the copy operation. + +nxagent-1.4.0-59 + +- Disabled use of caching and cleaning of images, if NX transport is + not used. + +nxagent-1.4.0-58 + +- Added timeout on convert selection operation. If timeout has not + expired and is there a pending operation any new request is dropped + and the client notified, until timeout expiration. + +- Corrected a bug that prevented to correctly store last convert se- + lection request time. + +nxagent-1.4.0-57 + +- The Xinput extension is now initialized at startup. This is of + little use because nxagent only needs to support the core pointer + and keyboard. Anyway this allows nxagent to get rid of the warn- + ings printed by some X clients on recent Linux versions when the + extension is not found. + +nxagent-1.4.0-56 + +- Fixed value returned by ConvertSelection. It was the cause of + possible slowndowns during KDE sessions. + +nxagent-1.4.0-55 + +- Agent icon now is loaded from a binary- + embedded Xpm image, if any attempt to + load the default Xpm file from the image + directory or from the path fails. + Removed code used in the old logo drawing + function. + +nxagent-1.4.0-54 + +- Enabled code for sending to client graphics + exposures. Redirecting the ones coming from + remote X server, only if agent window is not + fully visible, and calculating ourselves failure + in CopyArea/Plane and notifying clients. + The only drawback is that we can have double + refresh effect if agent window is covered. + +NOTE: Partially enabled MIT-SHM extension has + been developed but has not been included + in stable release. Included in version + nxagent-1.4.0-53-DAR1. + +nxagent-1.4.0-53 + +- Implemented a reliable technic to detect + if is there any window manager running on + the X server. + +nxagent-1.4.0-52 + +- Fixed a bug that prevented to correctly + notify the client of a successfull convert + selection. + +nxagent-1.4.0-51 + +- Removed a logging error in render initialization. + +nxagent-1.4.0-50 + +- Now we take the ownership of the selection + on "NX_CUT_BUFFER_SERVER" twice, in order + to solve bug in communication with nxclient + to let him see our main window and know that + agent established connection with X server. + +nxagent-1.4.0-49 + +- Fixed the colormask layout of the visual + used to put images on the real X server when + the drawable has an alpha channel, according + to the endianess of the X server. + +nxagent-1.4.0-48 + +- Moved up the render compatibility limit, + due to the inclusion of the support for render + cursor missing on the 0.2 version. + +nxagent-1.4.0-47 + +- Changing artsd forwarding port from display + + 8000 to display + 7000 + +- Stoping key release event if key press was + catched before. For Alt-F2/F4 combination. + +- Preserved the alpha data on drawables that + are not used by picture but have a depth of 32. + +nxagent-1.4.0-46 + +- Rewritten all the code regarding to the + acceleration for the Render creation of the + cursor, and removed the acceleration for + the animated cursor. + +nxagent-1.4.0-45 + +- The two RENDER operations creating cursors and + animated cursors have been accelerated by for- + warding the original operation to the X server. + +nxagent-1.4.0-44 + +- Fixed a problem in the clipboard procedure. + Now when we get a request of the selection + from an internal client we have to, if the + owner is on the X server, forward the request + to X, otherwise we have to pass the request + to our internal client. + But for a problem in this procedure we passed, + in some situation, the request to the internal + client even if the owner was on the other side. + +- Fixed a segmentation problem in the render + extension by removing composite trapezoid + operation on window. + +nxagent-1.4.0-43 + +- Added some pointer sanity check in the discon- + nect procedure. The problem was arising because + we were executing the code twice when after + began a voluntar disconnection the X connect- + ion was broken for a network failure. + +- Changed directory where nxagent gets the icon. + +- Fixed missing implementation of rendering + trapezoids. + +- Fixed bug in render extension when the nxagent + create cursor diffrent then 32 bits format. + +nxagent-1.4.0-42 + +- Solved segmentation fault, caused by a longjmp + on a stack context not previously saved. + +nxagent-1.4.0-41 + +- Added an exposures of the window in a resize + operation. + +nxagent-1.4.0-40 + +- Implemented a timeout on the opening of the X + display, if we get it we reject all well known + sockets. + +nxagent-1.4.0-39 + +- Corrected minor error on events handling. + +nxagent-1.4.0-38 + +- Removed in the resize window code some exposure + that generated useless traffic. + +- Option geometry is no more parsed in the option + file. + +nxagent-1.4.0-37 + +- When session is suspended and we get TERM signal + nxagent just exit instead of just breaking out of + dispatch loop because we get a terminate exception. + Cleared display variable after having closed the + connection with the X server. + +nxagent-1.4.0-36 + +- Refined some details in the ICC with nxclient. + +nxagent-1.4.0-35 + +- Implemented a new method to comunicate to nxclient, + the raise of the agent root window, taking the ownership + of the selection "A-{MD5 of session}". + Used the same selection to let nxclient comunicate to agent + by changing the property on the same string, when the user + choose by the administrator to terminate or suspend the + session. + +nxagent-1.4.0-34 + +- Key sequence to Suspend/Terminate session (Alt-F4). + +- Key sequence to Minimize session in fullscreen mode (Alt-F2). + +- Check if WM is started, for Alt-F2 sequence. + +- Corrected calculation geometry of exposed region + sent to client after reconnection. + This solve a serious memory leak of nxagent. + +- Fixed a bug in validate GC code that passed + a wrong pointer of tile to framebuffer. + +nxagent-1.4.0-33 + +- Changed the reconnection state machine in order + to let agent exit if has got the TERM signal. + +nxagent-1.4.0-32 + +- Fixed memory leak in option parser that wasted + memory if more than one occurence of 'option' + argument would have been parsed. + +- Removed a invalid read in Keyboard initialization. + Now kbtype option value is copyed instead that + referenced. + +- The X connection number is recorded only after + having cheched for display being successfully opened. + +nxagent-1.4.0-31 + +- Fixed memory leak problem caused by region not + beeing destroyed previously. + +- Fixed a memory leak in keyboard initialization. + +- Fixed a bug in the function that parse the option file, + we were reading the options in the format NAME=VALUE and + were passing it to the argument parser in the format + {NAME, VALUE}, without the prepending '-' in front of NAME. + +nxagent-1.4.0-30 + +- Readded option persistent in order to let nxagent + works with older nxserver that are still launching + nxagent with the persistent option. + +nxagent-1.4.0-29 + +- Corrected the message of the client dialog + asking if user want to suspend or terminate the + session. + +- Chenged the default value for persistence of session + in nxagent to true. Change the persistent option to + nopersistent in order to disable it. + +nxagent-1.4.0-28 + +- Added check on screen initialization of possible + memory allocation failure. + +- Changed the parsing policies of the option file. + Now we are just considering kbtype and geometry + options. + +- Removed testing code that forced rootless mode + when geometry is 100X100. + +- Correctly initialized and mapped the icon window + on fullscreen mode. + +nxagent-1.4.0-27 + +- Fixed lost memory problem caused by second + initialization of screen privates. Screen + privates is already initialized by miScreenInit + function. + +nxagent-1.4.0-26 + +- Added option command line option. This parameter + is used to show complete path to option file. + +- Added parser of the option file. + +- Now default value for fast copy area and fast + getimage is true. + +nxagent-1.4.0-25 + +- Done some cleanup to the initialization of the + defaults drawables at reconnection, and removed + a memory leak in the reopening of the Display. + +nxagent-1.4.0-24 + +- Changed the version number, printed at startup. + +- Removed a memory leak in the font reconnection stage. + +nxagent-1.4.0-23 + +- Removed a bug that messed up the render status info + if reconnected to a display with no render support. + Anyway nxserver should prevent agent to trying reconn- + ecting to such display. + +nxagent-1.4.0-22 + +- Enhanced the reconnection error reporting function. + +nxagent-1.4.0-21 + +- Get the ownership of selection NX_CUT_BUFFER_SERVER at reconnection + in order to let client knows that agent windows has started + successfully. + +nxagent-1.4.0-20 + +- Now we draw splash logo at reconnection. And destroy it and show + all other windows when reconnection has done all in once. We draw + it on default window instead that on root window, and we map root + window when reconnection has finished. + +nxagent-1.4.0-19 + +- Removed the old Xconnection descriptor and added the new one + to the device set, instead of resetting the entire enabled + device set, at reconnection. + +nxagent-1.4.0-18 + +- Reset the enabled devices set of descriptors, and properly + add to this set the the Xconnection descriptor. + +NOTE: This solves all the known solaris reconnection problems. + (The problem appear only on solaris because on this machine + the Xconnection descriptor is changing at reconnection.) + +nxagent-1.4.0-17 + +- Restored the previously owned primary selection, at reconnection. + Removed the handling of the return value of XSetSelectionOwner, + man page doesn't specify any return value. + +nxagent-1.4.0-16 + +- Added compatibility with older windows clients(Xserver) + that send a WM_DELETE_WINDOW client message WM_DELETE_WINDOW + to all top level window and so agent show more than one + NXDialog asking for confirmation, instead of sending just the + message to top level window that are visible and haven't set + the override redirect option. + +nxagent-1.4.0-15 + +- Ignored unmatched DirectColor visuals at reconnection + on a different display not providing it. + +nxagent-1.4.0-14 + +- Moved the render query extension in display + initialization from screen initialization. + +- Changed reconnection policy to disallow reconnect a + session that is using render to a server not providing it. + +nxagent-1.4.0-13 + +- Unified the screen opening function. + +- Changed the reconnection requirements + policy about geometry of X server. + Now agent doesn't accept changes of X server + root window size only if in fullscreen mode. + +nxagent-1.4.0-12 + +- Improved failure notification messagges in Display and + font code. + +nxagent-1.4.0-11 + +- Now visuals are properly recreated, in order to reconnect + to another X server. + +- Updated render formats at reconnection. + +nxagent-1.4.0-10 + +- Removed a serious memory leak at reconnection. + +nxagent-1.4.0-9 + +- Added after window reconnection the redisplay of the current + cursor. Done some general cleanup at cursor reconnection code. + +nxagent-1.4.0-8 + +- Unified tha atom creation at reconnect. + +nxagent-1.4.0-7 + +- Dix layer when creating a GC use a default real pixmap as + stipple but agent need a virtual one. This can cause + segmentation fault to agent if is there any apps that use the + default GC stipple created by dix, without changing it. + +nxagent-1.4.0-6 + +- Imported 1.4.0-1-DAR6 from the 1.4.0 development branch. + +- Handled reconnection of window's cursor still not + reconnected at window reconnection. (This because that cursor + is no more a server[nxagent] resource). + +- Set the last image client variable at reconnection in order + to use the visual cache indexed for client number. + Without this we could get a segmentation fault. + +- Handled properly the reconnection of animated cursor. + Modified the procedure of animated cursor creation + in order to empty some unused fields. + +- Removed a 4 bytes memory leak at reconnection. + +- Synced new tree with nxagent-1.3.2-23. + +- Finished the unify of PutImage at reconnection. + Added a Reconnection Trap in order to let screen functions + (like PutImage) knows that are working at reconnection time + and can behave differently. + +- Unified the code for the normal PutImage and the one's used at + reconnection. But the code that calculate the split is still + doubled. + +nxagent-1.4.0-5 + +- Imported 1.3.2-23 from the 1.3.2 development branch, and dropped + the previous 1.4.0 versions. + +nxagent-1.3.2-23 + +- Pixel hints are set according to the display's depth. Added the + defaults to be used on 16 bits. + +nxagent-1.3.2-22 + +- The pixel hint on Solaris is by default 0xffffff. The value can be + overridden by using the -hint option followed by the hex represen- + tation of the color, as in -hint 0xaabbcc. + +nxagent-1.3.2-21 + +- Asynchronous GetImages are now disabled. If fast GetImage mode is + enabled, agent will always try to guess the pixel to be used for + the solid pattern, based, at its best, on the geometry of the pro- + vided area. This behaviour can be overridden by passing the -slow + parameter on the command line. Slow mode is also the default when + selecting WAN or LAN link settings. + +- Code cleanup in preparation of the final release. + +nxagent-1.3.2-20 + +- New code uses sigaction to set the SIGHUP handler in persistent + mode. Contrarily to signal(), the sigaction call doesn't seem to + reset the handler to SIG_DFL after the signal has been caught. + This problem seems to be specific of Solaris. + +- Client messages of type WM_PROTOCOLS are now handled even when + a window manager is not detected at agent startup. + +- Removed handling of GraphicsExposure coming fron the real server. + Agent will still generate events in the MI. Code dealing with the + remote events needs to be better tuned as it seems to cause some + troubles with double refreshes. + +nxagent-1.3.2-19 + +- Starting from this version agent doens't use NXSync and NXKarma + messages to manage bandwidth arbitration among clients but makes + efficient use of the congestion notification messages introduced + in 1.3.1. A new handler has been added to manage the congestion + state. The handler will block, if needed, waiting for the decon- + gestion notification coming from proxy. + +nxagent-1.3.2-18 + +- Rewritten the block handlers to check the event queue more often. + The new code seems to greatly enhance responsiveness, especially + on fast links. + +- Now agent will handle the expose events coming from the remote + display inside the event dispatcher. + +- Created a new function collecting the expose events. Function is + optimized to add all the expose events for the same window to a + single region. Region is passed to the mi when the last event + has been processed. + +- Still dealing with GetImage from OpenOffice. Now we try to match + the geometry of the incoming requests with known geometry of most + of its graphic elements. It seem to work on Fedora. + +nxagent-1.3.2-17 + +- Added swapping of image data in nxagentGetImage() when connecting + to a display having a different image byte order than the agent + server. + +- Added a new nxagentImageReformat() function in GCOps.c. + +- Now agent will not try to pack images having a data size smaller + than 768 bytes. The previous threshold was set to 64. The Mandrake + vesion of KDE seems to send lot of such small images. Compressed + through JPEG, these images obtain a very poor ratio of nearly 1:1. + +- Added a function translating and sending the GraphicsExposures + events received from the remote server to the agent's clients. + +- Renamed the functions providing the ad-hoc handling of remote X + events. + +nxagent-1.3.2-16 + +- Implemented a cache for the alpha channel data. With clients + making heavy use of the alpha blending, the new cache is able to + cut by nearly 30% the traffic incoming to proxy, offering compara- + ble savings in CPU performance. While proxy is usually able to + cache almost all the alpha traffic, when caching is not enabled + (f.e. when link setting is WAN or LAN) this data is sent uncomp- + ressed by the agent. Tests running common desktop environments + showed that alpha channel could weight up to 2 times the corres- + ponding data generated by the packed images. + +- Fixed the compilation warnings in NXrender.c. + +nxagent-1.3.2-15 + +- Rewritten handling of GetImage from dispatcher down to GCOps. If + the fast GetImage mode is enabled agent will use the asynchronous + calls provided by nxcompext to get data from the real server. Data + collected from the last get image performed is preserved and the + upper left pixel is used to guess a solid background. + +- Added a nxagentGetBackgroundImage() function to apply a similar + mechanism when the nxagent window isn't fully visible. Previously + a solid white background was returned. The new handling seems to + correctly match the window background in most cases. + +- Fixed a problem passing the bytes per line value when creating a + XYPixmap image. The previously calculated value didn't take into + account the depth of the image. + +- Now image's bytes per line, length and visual are calculated by + using a few utility functions added to GCOps.c. + +- Added declaration of the nxagentVisibility related variables to + Window.h. + +nxagent-1.3.2-14 + +- On Fedora xbcomp configuration fails when agent is run nested. + This causes keyboard to ignore most AltGr keys. Strangely enough + this behaviour has been observed only with KDE while GNOME does + not seem to be affected. Reason is to be investigated. + +- Auto-repeat mode of the agent's keyboard device is now always + disabled. Agent will leverage auto-repeated keystrokes genera- + ted on the real server even when propagating device configura- + tion changes. + +- The info output telling if agent will propagate the changes to + devices' setting is now printed after having initialized the + screen. The purpose would be to verify if agent is running in + fullscreen mode and there is no WM on the real display. In this + case we should forcibly propagate device configuration changes. + Unfortunately, due to the way intern atoms are collected, this + is not going to work on platforms where sessions are likely to + run on an existing X server. + +nxagent-1.3.2-13 + +- Fixed a problem with XYPixmaps being used in PutImage with the + wrong left pad. This is a step forward in the solution of the + corrupted masks displayed by Mozilla when showing some animated + GIFs. + +- By selecting 'fast' mode nxagent will now skip real XGetImage + operations on windows. This becomes the default in the case of + MODEM, ISDN and ADSL links. In theory X clients should never do + that. In practice a few naive programs and libraries (like, sur- + prisingly enough, a famous Linux office automation suite) do, + mainly to compose images with the window's backgound. Why don't + they compose content into a Pixmap? + +- Improved the implementation of CompositeGlyphs. It now uses a + single call to XRenderCompositeText instead of splitting the + output in multiple RENDER requests. + +- In previous versions file NXmiwindow.o was not linked into the + resulting nxagent. This solves the problem of missing repaints + in CDE and other Xt applications. Be sure you upgrade nx-X11 + to version nx-X11-1.3.2-2. + +- Added a warning when the change keyboard control or the change + pointer control functions are called. + +nxagent-1.3.2-12 + +- Added bit-swapping of glyphs having depth 1 when agent has a + different bitmap-bit-order than the X server. + +- The KeyRelease event's timestamp calculation, accounting for + differences in time between the local and the remote machine, + will now use the timestamp taken from the last KeyPress. Using + the timestamp of the last event was sometimes causing time to + go backward with the result that server could remain grabbed. + This solves the long-standing "mouse stop responding" problem. + +- Fixed a problem handling the alpha channeled visual introduced + while experimenting with the new server endianess layout. + +nxagent-1.3.2-11 + +- Added the Reset option to options repository. By default agent + will skip server reset when the last client disconnects. This is + equivalent to passing the -noreset option to a standard XFree86 + server. To restore the original behaviour the new -reset option + can be used on the command line. + +- Moved the SharedMemory and DeviceControl options to the options + repository. + +- A basic session, still leveraging all the default facilities, can + now be run as: nxagent -name NX -geometry 800x600+10+100 :1. The + -fp unix/:7100 option can be added to enable access to the X font + server. + +- Fixed a "unused variable" warning in Cursor.c. + +nxagent-1.3.2-10 + +- Rootless mode. Some cleanup in initialization. + +- Rootless mode. Working at the configure-window errors. + +nxagent-1.3.2-9 + +- Removed limitations when running nxagent nested inside another + nxagent server. Now both render extension and packing of images + are enabled. + +- The nxagent X server now inherits its endianess from the host + architecture, instead of assuming the same endianess of the con- + necting client. This fixes the remaining problems running ses- + sions nested inside another nxagent server. + +- Removed any reference to ReformatImage(). + +nxagent-1.3.2-8 + +- Changed the way the agent server handles images internally. + The inherited Xnest code used to set the server's image order + to the same order of the remote X display. This caused agent + to create images in the internal frame-buffer with a different + endianess in respect to images got from X clients. + +- The new image handling code seems to solve all the known image + endianess problems, for example cursors created on big-endian + displays with a wrong shape or glyphs being showed flipped when + retrieving the image data from the virtual frame-buffer. + +- As an added bonus the new code seems to double the performance + of the SPARC Solaris server when accessing i386 clients. + +- Commented out all the existing calls to ReformatImage(). Code + needs now extensive testing to see if any of the calls must be + actually restored. + +- Replaced calls to index() with strchr(). + +nxagent-1.3.2-7 + +- Solved a potential memory error when accessing a client or a + window pointer in clipboard management code after the resources + had been destroyed. Added a nxagentClearClipboard() function to + be called before a client or a window is destroyed to get rid + of any reference to the disposed resources. + +- Auto-repeated keystrokes generated by agent from inside the + virtual keyboard device are now ignored. Agent will correctly + honor auto-repeated keystrokes generated by the real X server. + This is actually the expected behaviour. The former implemen- + tation triggered an annoying bug, with keystrokes being inad- + vertedly auto-repeated in the case of high latency on the + network link. + +- Agent will now ignore the pointer settings changes generated + inside the remote session. The original behaviour was to reset + the pointer values (for example acceleration) to the X factory + settings at session startup. Agent will now inherit whatever + values are set on the real X display. + +- Added a -noignore parameter. When passed, agent will propagate + to the real X server any change to keyboard and pointer control + settings operated by its own X clients. + +nxagent-1.3.2-6 + +- Fixed problem with glyphs being drawn clipped in the virtual + frame buffer. This is not yet the final solution but it seems + to work in all the circumstances where problem was observed + in the past. Problem seems to be caused by scratch pixmaps + being requested with a width and height smaller than actually + required. Note anyway that pixmap's buffer seems to be never + accessed beyond its boundary. This probably means that memory + for the pixmap is originally allocated using the right size. + +- Moved backing-store selection to options repository. Now by + default the backing-store mode is set to WhenRequested. This + means that, in most cases, there is no need to pass the -bs + option on the command line. + +- Code cleanup in Render.c, NXrender.c, NXglyph.c. + +nxagent-1.3.2-5 + +- Fixed initialization of all the supported depths. Previous + versions correctly initialized the various depths but still + failed to advertise the support of any other depth than the + default depth supported by the remote X server. + +- Persistent mode. We now correctly propagate the pixmap ID of + the parent to the virtual pixmap at reconnection. This fixes + the reconnection errors when render extension is enabled. + +- Persistent mode. Solved the refresh problems at reconnection. + Problems were generated by the lack of window parent's ID at + the time session was reconnected. + +- Changed the agent's behaviour at the time the close button is + pressed. If agent is running in persistent mode a new dialog + is showed with the option to suspend the session. + +nxagent-1.3.2-4 + +- Persistent mode. At the time the proxy connection is reset the + per-client unpack geometry information is cleared. This makes + agent find out that a new unpack geometry is needed as soon as + the display is reconnected. + +- Persistent mode. Lot of logging added in order to trace use of + resources as long as they are recreated. The current version + fails to correctly restore the picture information when render + is enabled. + +nxagent-1.3.2-3 + +- Finally fixed all the problems with missing initialization of + pixmap formats. The screen info is now correctly set up even + when the remote display doesn't support all the target depths. + Many thanks to Michael L Torrie who helped me to reproduce the + problem and come to a solution. + +- Moved initialization of depths, default drawables and pixmap + formats to their own functions in Display.c. + +nxagent-1.3.2-2 + +- Fixed the nxagentDestroyPixmap() function to correctly take into + account the reference counter of the virtual pixmaps. This solves + the crashes observed when running some GTK clients like xchat. + +- Added a function Pixmap.c to forcibly destroy the pixmaps created + in the virtual framebuffer when the parent pixmap is destroyed. + +- This version contains some verbose output intended to better test + the new behaviour. The output will be removed in future versions. + +nxagent-1.3.2-1 + +- More cleanup in Pixmap.c. + +- Rewritten nxagentCreatePixmap(). Corrected an error where the + bitsPerPixel field was set to the pixmap's depth instead of the + result of BitsPerPixel(depth). This finally solves the problem + of text being incorrectly rendered in the virtual framebuffer. + +- Corrected the X error returned at the end of session when trying + to free a pixmap with an invalid id. + +- Opened the 1.3.2 branch. + +nxagent-1.3.1-32 + +- Cleanup of Pixmap.h/Pixmap.c. Renamed macros according to the + nxagent naming conventions. + +nxagent-1.3.1-31 + +- When running in fullscreen mode, grab and ungrab of pointer and + keyboard is performed in new functions, placed in Events.c. + +- The event loop now checks if the enter/leave notify carries a + NotifyInferior detail and, in this case, doesn't perform the grab. + This saves half the amount of grabs (and the related roundtrips) + performed by the previous version. + +- Ungrab of pointer is now performed whenever the cursor leaves the + fullscreen window. In previous version only the keyboard was + explicitly ungrabbed. + +- Added a warning in the event loop when receiving a MappingNotify. + This event is presently unhandled and seems to be reported, as a + consequence of the selected event mask, only by some X servers. + +nxagent-1.3.1-30 + +- Reverted the patch introduced in Pixmap.c. The whole issue is + being investigated in its ramifications up to the virtual frame + buffer. + +nxagent-1.3.1-29 + +- Fixed a problem in the nxagentDestroyPixmap function where the + reference counter of pixmaps could be decremented twice. This + could lead to agent trying to free the pixmaps more than once. + +- On Solaris there is no description for pc105 keyboard model. As + a workaround we consider pc104 to be the closest approximation. + +nxagent-1.3.1-28 + +- Fixed a bug in the create window procedure. With some clients, + like Maelstrom and xmame, the creation of the main window was + failing due to the wrong colormap and visual attributes used + by agent on the real X server. + +- In fullscreen mode the keyboard is now grabbed at the time we + receive an EnterNotify event. This fixes a problem at startup + observed on some Debian based distributions where agent didn't + receive the keyboard focus until user had minimized and then + brought to front the agent's window. The grab is now correctly + performed by using the timestamp of the remote X server ins- + tead of our local timestamp. + +- In NXdixfonts.c strings corresponding to names of fonts and + font aliases cached by nxagent were missing the terminating + zero. + +- In function InitClientPrivates fixed the missing initializa- + tion of the is_ignored member of the ClientPriv structure. + +- Added the Persistent option to Options repository. The flag is + intended to replace the old nxagentEnableReconnect variable. + +nxagent-1.3.1-27 + +- Fixed a memory allocation problem in Keyboard.c. A string was + allocated in the heap without making enough room for the trail- + ing zero. + +nxagent-1.3.1-26 + +- Added further run-time checks to verify that pixmaps are not + created with bad bit-per-plane settings. This problem seems to + be caused by lack of support by nxagent of some combinations + of depth and visual when the render extension is enabled. If + this is the case, hide the render extension to new clients and + force any subsequent render operation to return a BadRequest + error. This required including extension.c from dix. A new + NXextension.c file is added to the distribution. + +- A problem was reported by Valgrind about reading the first 4 + bytes just after the block allocated in fbCreatePixmap from + nxagentCreatePixmap. A quick fix was added to pixmap.c from + dix so that AllocatePixmap adds 4 additinal bytes to each + buffer. + +nxagent-1.3.1-25 + +- Fixed a memory corruption error. The original AllocateGlyphSet + from render/glyph.c could be called instead of the NX counter- + part defined in NXglyph.c. This could lead to the missing + allocation of the trailing remote glyphset id field. + +- Added initialization of an otherwise usused string in function + nxagentPropagateArtsdProperties(). The whole string is probably + to be removed in future versions. + +- Moved the flag used to avoid reentrancy in GCOps to a separate + Trap header and source. + +- Further cleanup. Removed the zombie file NXglyphcurs.h. + +- Added missing initialization of the picture pointer in private + window's data in nxagentCreateWindow. + +nxagent-1.3.1-24 + +- Added the missing timeout when calling WaitForSomething() at + startup. The bug caused the splash to remain on screen until + a further event was received. + +- Fixed a BadAtom error on Windows during initialization. Error + was caused by a bad attempt to change the NX_AGENT_SIGNATURE. + +- Hunting the 0 bits-per-plane drawable bug in nxagentValidateGC. + Added tracing output and additional checks. GC validation is + skipped if it is not possible to recover an appropriate value. + +- Ensured that nxagentDisplayName is set before calling the post + initialization procedure. + +nxagent-1.3.1-23 + +- When session is run nested inside another NX X agent, all the + optimizations regarding remote expose events on fully visible + windows are disabled. This solves the refresh problems encoun- + tered when covering the nested session with a window from the + local X server. + +- Reusing NX_AGENT_SIGNATURE atom to detect nested operation. + Atom is created internally to the agent server at startup, + before any atom on the real display. + +- Fixed construction of caption used for dialog boxes spawn by + agent. The previous algorithm failed to identify the correct + string in parameter -name passed on the command line. + +nxagent-1.3.1-22 + +- Ensured that state of keyboard modifiers is initialized with + values from the real X server when the first key stroke is + pressed by the user. + +- Fixed the X_SetInputFocus errors generated at session startup. + +- Rootless mode. Ensured that remote expose events are always + reported by the remote proxy. This is a temporary fix looking + forward for better handling of visibility events. + +nxagent-1.3.1-21 + +- Saved a GetWindowAttributes and a GetGeometry in the function + drawing the splash screen. + +- Better handling of splash at startup. Removed the flickering on + Windows without recurring to another atom. This is achieved by + optimizing drawing and delaying mapping of the main windows. + +- Modified the magic values activating rootless mode to 100x100. + +- Removed modifications introduced in 1.3.1-20. + +nxagent-1.3.1-20 + +- Working on eliminating the splash screen flickering on Windows + and Darwin. Checked if the NX_SPLASH atom has been created by + the NX X server. If this is the case, we let the NX X server + show the splash screen on our behalf. + +nxagent-1.3.1-19 + +- Improved the initialization phase by removing a GetProperty, an + InternAtom and two GetInputFocus round-trips. + +- Added appropriate masking of the state bits reported by the + XkbStateNotifyMask event. + +- Added a simple mechanism during the itialization phase to trace + the use of X server replies. + +nxagent-1.3.1-18 + +- Made some order in functions loading the NX icon. + +- Removed some more zombie files from agent distribution. Now only + the files imported from DIX and MI have name prepended with NX. + +nxagent-1.3.1-17 + +- Moved names and values of intern atoms created by agent in their + specific header and source. + +- We temporarily force rootless mode if user provides a geometry + of 801x601. This is intended to simplify testing. Note that if + rootless is selected, we'll anyway disregard any geometry set + by the user, assuming the geometry of the real display. + +nxagent-1.3.1-16 + +- We are checking now whether NX_IDENTITY intern atom is created + before NX_SPLASH. We want NX X servers to show the splash on our + behalf, so if NX_SPLASH is already interned, than we just skip + the splash procedure. + +nxagent-1.3.1-15 + +- Rootless mode. Fixed a segfault handling ConfigureNotify events + on top-level windows. + +- Moved handling of ClientMessages coming from proxy in a separate + function. + +nxagent-1.3.1-14 + +- Rewritten the code dealing with key modifier changes. Now we + use XKB events instead of synchronous XkbGetIndicatorState() + calls. + +- Moved activation of keyboard and pointer events to Events.c. + +- Removed pointer motion optimizations as a better logic, taking + in account the selected link speed, is already implemented in + proxy. + +nxagent-1.3.1-13 + +- Renamed the -reconnect option as -persistent. + +- Rootless mode. Agent's root windows are not mapped at startup. + +- Removed the zombie file glyphcurs.c from agent distribution. + +nxagent-1.3.1-12 + +- Corrected a typo in the new CopyArea code in GCOps.c where: + + if (srcx > nxagentWidth) srcx = nxagentWidth; + if (srcy > nxagentHeight) srcx = nxagentHeight; + + had to be: + + if (srcx > nxagentWidth) srcx = nxagentWidth; + if (srcy > nxagentHeight) srcy = nxagentHeight; + +- Added handling of the fullscreen command line parameter to the + options repository. + +- Added agent geometry parameters to the options repository. + +nxagent-1.3.1-11 + +- Rootless mode. Added handling of configuration events reported + for the top-level windows. + +- Rootless mode. Children of the root window get the event mask + selected when the window is created. This makes the keyboard + work at least with xterm and other simple clients. There are + still problems with the pointer events. + +- Created new Splash.h and Splash.c sources file to contain the + few splash screen procedures that were previously sparsed in + multiple files. + +- Added traces in all the window creation procedures and in the + initialization routines called at startup. + +- Renamed some source files to make simpler to identify what is + imported from DIX and what actually pertains to agent. + +nxagent-1.3.1-10 + +- Added the missing RestackWindow screen operation. This solves + problems of incorrect stacking order observed in menus when + using the drop shadow feature in the latest KDE versions. + +nxagent-1.3.1-9 + +- The new standard for checking previous inclusion of headers is + by verifying definition of _Filename_H_ where Filename is the + base name of the file, for example __Options_H__ in the case + of "Options.h". This is intended to be a step in reducing the + number of defines in code prefixed with NXAGENT. + +- Updated NX copyright to year 2004. Placed copyright statement + regarding NXAGENT and NX modifications to the Xnest software + at the beginning of the file. Checked again if credit is given + to all the existing copyright owners. + +nxagent-1.3.1-8 + +- Added a new Options repository to store the values currently + dispersed all over around. The new macros nxagentOption(option) + and nxagentChangeOption(option, value) should be used from now + on to access the important values affecting agent's operations. + +- General cleanup of code. Removed the remaining references to + the Xnest legacy code. + +nxagent-1.3.1-7 + +- Some steps forward toward rootless agent. Now all the top level + windows are correctly created. Drawing to the real screen seems + to work without problems. It is still not possible to get events + in the event loop and the remote WM is interfering with the WM + on the local display. + +- More cleanup of code. Some changes to parts added since 1.3.1-5. + +nxagent-1.3.1-6 + +- A drawable with 0 bpp can somehow arrive to the fb layer. The + problem needs to be better investigated. In the meanwhile a + quick check is added to correctly identify the ill condition. + +- Small fix to allow Num/Caps lock synchronization also on the + windows platform. This is still to be considered beta quality. + +- New options -slow and -fast added to agent. When "fast mode" is + not set, agent will query the remote X server to get real content + of drawables. When fast mode is enabled, agent will save the + round-trip by just clearing the drawable to its background. The + default mode is "slow", thus agent will always query the remote + server. When "fast mode" is explicitly set or when NX transport + is detected and the link is one of MODEM, ISDN and ADSL, agent + will default to "fast mode". This behaviour can be overridden by + system administrators by setting the key AGENT_EXTRA_OPTIONS_X + to "-slow" in node configuration. + +nxagent-1.3.1-5 + +- Created framework for rootless agent. Added a -rootless option. + +- Slowly going toward a better organization of nxagent internals. + Renamed some files and moved things around. Changed some comments + in Screen.c to be more explainatory. + +nxagent-1.3.1-4 + +- Changed default keyboard model to "pc102" (was "pc101") to correct + problems with "<" and ">" keys on the German keyboards and, poten- + tially on other layouts. + +- Added new parameter -kbtype to handle both geometry and layout in + a single form, for example pc102/pl. Parameter -keyboard is still + supported for backward compatibility. + +- Synchronization of Num and Caps lock status is now done comparing + the real keyboard and the internal state at the time nxagent gets + the focus. If state doesn't match, a fake keyboard event is sent. + +nxagent-1.3.1-3 + +- Fixed a further problem on CopyArea between windows and pixmaps. + +nxagent-1.3.1-2 + +- Implemented CopyArea on framebuffer when copying from windows to + pixmaps. Added the -slow command line switch to let nxagent get + the real content of the window from the X server. This requires + an expensive round-trip so it is disabled by default. + +nxagent-1.3.1-1 + +- Opened the 1.3.1 branch. + +nxagent-1.3.0-32 + +- Fixed a bug on 16 bpp displays using render extension. Now only + images which are used by render pictures and which have depth 32 + are created with a different visual color mask. This saves a big + amount of SetUnpackColormap requests. + +nxagent-1.3.0-31 + +- Fixed a bug in nxagentComposite routine. The macro nxgentPicturePriv + was used without checking for a null pointer argument. + +nxagent-1.3.0-30 + +- Limitations on bandwidth introduced whenever the agent's window + is covered are now disabled by default. They can be enabled by + specifying the -limit option on the command line. The -nolimit + option is left for compatibility with the previous versions. + This handy feature caused complaints in the past from users who + instruct window managers to not move the window having focus on + top of the stacking order. + +nxagent-1.3.0-29 + +- Removed the warnings issued at compile time. + +nxagent-1.3.0-28 + +- Replaced the corrupted file nxagent.xpm with the original version. + +nxagent-1.3.0-27 + +- Hopefully fixed all the remained memory leaks. Most problems were + due to agent's render extension not freeing resources on X server. + +- Added support for big-endian X server display on render extension. + Glyphs are reformatted according with the destination order. + +- Added per client information for SetUnpackGeometry, now the unpack + routines should have the correct information for the color mask at + the end of the split process. + + +nxagent-1.3.0-26 + +- Changed the message printed in the log when leaving the dispatch + loop from 'Error' to 'Info'. + +- Moved initialization of _NXFlushSize to nxcompext in order to set + value at the time NXGetControlParameters() is called. + +nxagent-1.3.0-25 + +- Content of selection is now acquired using a single round-trip. + If content exceeds 262144 bytes, it is truncated at that size. + This works in most situations, at least with text, that, by the + way, is the only target supported at the moment. An improvement + would be to modify the state machine in a way that the remaining + data part is got using a second round-trip. This is not difficult + to do and can be considered for future releases. + +- In handling of clipborad we had to disable check on multiple + convert selection requests from the same client. There is a bug + in the algorithm that prevents the counter to be reset at the + appropriate time. This is to be investigated. + +nxagent-1.3.0-24 + +- Added asynchronous handling of GetProperty requests and replies + using the NXCollectProperty and NXGetCollectedProperty requests + and the NXCollectPropertyNotify event in NXclipboard.c and in + Event.c. Implementation is not complete yet and can sometimes + cause X clients to misbehave. + +- Function xnestBitBlitHelper() now always returns NullRegion. + Handling of graphical expose events should be rewritten so that + regions are always generated internally to nxagent. Returning a + null region without checking our event queue, anyway, saves a + flush of the display buffer and doesn't seem to affect the + functionalities. + +- This version comprises modifications to Events.c, GCOps.c, + NXClipboard.c, NXwindow.c and Window.c where I found XSync() + messages (or code used to just send XSync() messages) outside + any #ifdef ..._DEBUG. + +nxagent-1.3.0-16 + +- A dialog is showed at startup if proxy was not able to load a + persistent cache. + +- Reflected changes introduced in NXGetControlParameters() to add + more detailed information about the compression settings. + +- Fixed a potential bug with the name of the agent's display at the + time a dialog had to be showed. String was allocated with only 6 + characters. This could lead to dialogs not being showed using + display ports greater than 9999. + +- NX.h is now included by NXControl.h. Removed #include directives + from other files. diff --git a/programs/Xserver/hw/nxagent/Cursor.c b/programs/Xserver/hw/nxagent/Cursor.c index 9ed7c23..e27415b 100644 --- a/programs/Xserver/hw/nxagent/Cursor.c +++ b/programs/Xserver/hw/nxagent/Cursor.c @@ -293,31 +293,7 @@ void nxagentRecolorCursor(ScreenPtr pScreen, CursorPtr pCursor, Bool nxagentSetCursorPosition(ScreenPtr pScreen, int x, int y, Bool generateEvent) { - /* - * Don't warp the cursor if the requesting client - * is the server client itself or a shadow agent. - */ - - if (requestingClient != NULL && - requestingClient != serverClient && - nxagentClientHint(requestingClient) != NXAGENT_SHADOW) - { - int i; - - #ifdef TEST - fprintf(stderr, "nxagentSetCursorPosition: Moving the cursor at position [%d,%d].\n", - x, y); - #endif - - for (i = 0; i < nxagentNumScreens; i++) - { - XWarpPointer(nxagentDisplay, nxagentDefaultWindows[i], - nxagentDefaultWindows[pScreen->myNum], - 0, 0, 0, 0, x, y); - } - } - - return True; + return 1; } void nxagentReconnectCursor(pointer p0, XID x1, pointer p2) diff --git a/programs/Xserver/hw/nxagent/Display.c b/programs/Xserver/hw/nxagent/Display.c index 2c5450d..f803d29 100644 --- a/programs/Xserver/hw/nxagent/Display.c +++ b/programs/Xserver/hw/nxagent/Display.c @@ -2414,6 +2414,8 @@ Bool nxagentReconnectDisplay(void *p0) nxagentPackQuality = -1; nxagentSplitThreshold = -1; + nxagentRemoteMajor = -1; + nxagentInstallSignalHandlers(); nxagentInstallDisplayHandlers(); diff --git a/programs/Xserver/hw/nxagent/Display.c.orig b/programs/Xserver/hw/nxagent/Display.c.orig new file mode 100644 index 0000000..db70434 --- /dev/null +++ b/programs/Xserver/hw/nxagent/Display.c.orig @@ -0,0 +1,2752 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */ +/* */ +/* NXAGENT, NX protocol compression and NX extensions to this software */ +/* are copyright of NoMachine. Redistribution and use of the present */ +/* software is allowed according to terms specified in the file LICENSE */ +/* which comes in the source distribution. */ +/* */ +/* Check http://www.nomachine.com/licensing.html for applicability. */ +/* */ +/* NX and NoMachine are trademarks of Medialogic S.p.A. */ +/* */ +/* All rights reserved. */ +/* */ +/**************************************************************************/ + +/* + +Copyright 1993 by Davor Matic + +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. Davor Matic makes no representations about +the suitability of this software for any purpose. It is provided "as +is" without express or implied warranty. + +*/ + +#include <signal.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <unistd.h> +#include <time.h> +#include <errno.h> + +#include <X11/X.h> +#include <X11/Xproto.h> +#include "screenint.h" +#include "input.h" +#include "misc.h" +#include "scrnintstr.h" +#include "servermd.h" +#include "windowstr.h" +#include "dixstruct.h" + +#ifdef WATCH +#include "unistd.h" +#endif + +#include "NXalert.h" + +#include "Agent.h" +#include "Display.h" +#include "Visual.h" +#include "Options.h" +#include "Error.h" +#include "Init.h" +#include "Args.h" +#include "Image.h" +#include "Icons.h" +#include "Render.h" +#include "Font.h" +#include "Reconnect.h" +#include "Events.h" +#include "Dialog.h" +#include "Client.h" +#include "Splash.h" +#include "Screen.h" +#include "Handlers.h" + +#include "NX.h" +#include "NXlib.h" + +#include NXAGENT_ICON_NAME + +/* + * Set here the required log level. + */ + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef WATCH + +Display *nxagentDisplay = NULL; +XVisualInfo *nxagentVisuals = NULL; +Bool nxagentTrue24 = False; + +int nxagentNumVisuals; +int nxagentXConnectionNumber; + +int nxagentIOErrorHandler(Display *display); + +static Bool nxagentDisplayInfoSaved = False; +static Display *nxagentDisplayBackup = NULL; +static XlibGC nxagentBitmapGCBackup = NULL; +static XVisualInfo *nxagentVisualsRecBackup; +static int nxagentNumVisualsRecBackup; +static int nxagentNumDefaultColormapsRecBackup; +static int *nxagentDepthsRecBackup; +static int nxagentNumDepthsRecBackup; +static int nxagentDefaultDepthRecBackup; +static int nxagentDisplayWidthRecBackup; +static int nxagentDisplayHeightRecBackup; +static Bool nxagentRenderEnableRecBackup; +static Bool *nxagentVisualHasBeenIgnored; + +static enum +{ + NOTHING = 0, + OPENED, + GOT_VISUAL_INFO, + ALLOC_DEF_COLORMAP, + GOT_DEPTH_LIST, + GOT_PIXMAP_FORMAT_LIST, + EVERYTHING_DONE +} reconnectDisplayState; + +int nxagentDefaultVisualIndex; +Colormap *nxagentDefaultColormaps = NULL; +int nxagentNumDefaultColormaps; +int *nxagentDepths = NULL; +int nxagentNumDepths; +XPixmapFormatValues *nxagentPixmapFormats = NULL; +XPixmapFormatValues *nxagentRemotePixmapFormats = NULL; +int nxagentNumPixmapFormats; +int nxagentRemoteNumPixmapFormats; +Pixel nxagentBlackPixel; +Pixel nxagentWhitePixel; +Drawable nxagentDefaultDrawables[MAXDEPTH + 1]; +Pixmap nxagentScreenSaverPixmap; + +/* + * Also used in Cursor.c. There are huge problems + * using GC definition. This is to be reworked. + */ + +XlibGC nxagentBitmapGC; + +/* + * The "confine" window is used in the nxagentConstrainCursor + * procedure. We are currently overriding the original Xnest + * behaviour. It is unclear what this window is used for. + */ + +Window nxagentConfineWindow; + +Pixmap nxagentIconPixmap; +Pixmap nxagentIconShape; +Bool useXpmIcon = False; + +unsigned int nxagentLogoColor(unsigned int value); +Bool nxagentMakeIcon(Display *display, Pixmap *nxIcon, Pixmap *nxMask); + + +static void nxagentInitVisuals(void); +static void nxagentSetDefaultVisual(void); +static void nxagentInitDepths(void); +static void nxagentInitPixmapFormats(void); + +static int nxagentCheckForDefaultDepthCompatibility(void); +static int nxagentCheckForDepthsCompatibility(int flexibility); +static int nxagentCheckForPixmapFormatsCompatibility(void); +static int nxagentInitAndCheckVisuals(int flexibility); +static int nxagentCheckForColormapsCompatibility(int flexibility); + +/* + * FIXME: These must definitely become local. + */ + +XVisualInfo pV; +unsigned int r, b, g, or, ob, og, off; + +/* + * Save Internal implementation Also called in Reconnect.c. + */ + +Display *nxagentInternalOpenDisplay(char *display); + +#ifdef NXAGENT_TIMESTAMP +unsigned long startTime; +#endif + +/* + * This is located in connection.c. + */ + +extern void RejectWellKnownSockets(void); + +int nxagentServerOrder() +{ + int whichbyte = 1; + + if (*((char *) &whichbyte)) + return LSBFirst; + + return MSBFirst; +} + +unsigned int nxagentLogoColor(unsigned int value) +{ + /* + * Takes a color value in RGB24 (0xff0000, 0x00ff00, + * 0x0000ff) and converts it into an equivalent for + * the current visual. + */ + + int cr=0, cg=0, cb=0; + + cr = (value >> or) &r; + cg = (value >> (og - 8)) &g; + cb = (value >> (ob - 16)) &b; + + return (cr | cg | cb); +} + +/* + * FIXME: This error handler is not printing anything + * in the session log. This is OK once the session is + * started, because the error is handled by the other + * layers, but not before that point, as the agent + * would die without giving any feedback to the user + * (or, worse, to the NX server). We should check how + * many requests have been handled for this display + * and print a message if the display dies before the + * session is up and running. + */ + +/* + * FIXME: This should be moved to Error.c, The other + * handlers should be probably moved to Handlers.c. + */ + +int nxagentIOErrorHandler(Display *display) +{ + #ifdef TEST + fprintf(stderr, "nxagentIOErrorHandler: Got I/O error with nxagentException.ioError [%d].\n", + nxagentException.ioError); + #endif + + nxagentException.ioError++; + + #ifdef TEST + fprintf(stderr, "nxagentIOErrorHandler: Set nxagentException.ioError to [%d].\n", + nxagentException.ioError); + #endif + + return 1; +} + +/* + * Force a shutdown of any connection attempt + * while connecting to the remote display. + * This is needed to avoid a hang up in case + * of loopback connections to our own listen- + * ing sockets. + */ + +static void nxagentRejectConnection(int signal) +{ + #ifdef TEST + fprintf(stderr, "nxagentRejectConnection: Going to reject client connections.\n"); + #endif + + RejectWellKnownSockets(); + + #ifdef TEST + fprintf(stderr, "nxagentRejectConnection: Setting new alarm to 5 seconds from now.\n"); + #endif + + /* + * A further timeout is unlikely to happen + * in the case of loopback connections. + */ + + alarm(5); +} + +/* + * Ignore the signal if the NX transport is + * not running. + */ + +static void nxagentSigusrHandler(int signal) +{ + #ifdef TEST + fprintf(stderr, "nxagentSigusrHandler: Nothing to do with signal [%d].\n", + signal); + #endif +} + +static void nxagentSighupHandler(int signal) +{ + #ifdef TEST + fprintf(stderr, "nxagentSighupHandler: Handling signal with state [%s] transport [%d] server " + "generation [%ld].\n", DECODE_SESSION_STATE(nxagentSessionState), + NXTransRunning(NX_FD_ANY), serverGeneration); + #endif + + if (signal != SIGHUP) + { + #ifdef PANIC + fprintf(stderr, "nxagentSighupHandler: PANIC! Invalid signal [%d] received in state [%s].\n", + signal, DECODE_SESSION_STATE(nxagentSessionState)); + #endif + + return; + } + + if (dispatchException & DE_TERMINATE) + { + #ifdef TEST + fprintf(stderr, "nxagentSighupHandler: Ignoring the signal while terminating the session.\n"); + #endif + + return; + } + else if (nxagentSessionState == SESSION_UP) + { + if (nxagentOption(Persistent) == 1) + { + #ifdef TEST + fprintf(stderr, "nxagentSighupHandler: Handling the signal by disconnecting the agent.\n"); + #endif + + nxagentException.sigHup++; + } + else + { + #ifdef TEST + fprintf(stderr, "nxagentSighupHandler: Ignoring the signal with persistency disabled.\n"); + #endif + } + + return; + } + else if (nxagentSessionState == SESSION_STARTING) + { + #ifdef TEST + fprintf(stderr, "nxagentSighupHandler: Handling the signal by aborting the session.\n"); + #endif + + nxagentException.sigHup++; + + return; + } + else if (nxagentSessionState == SESSION_DOWN) + { + if (NXTransRunning(NX_FD_ANY) == 1) + { + #ifdef TEST + fprintf(stderr, "nxagentSighupHandler: Handling the signal by aborting the reconnection.\n"); + #endif + } + else + { + #ifdef TEST + fprintf(stderr, "nxagentSighupHandler: Handling the signal by resuming the session.\n"); + #endif + } + + nxagentException.sigHup++; + + return; + } + + #ifdef WARNING + fprintf(stderr, "nxagentSighupHandler: WARNING! Ignoring the signal in state [%s].\n", + DECODE_SESSION_STATE(nxagentSessionState)); + #endif +} + +static void nxagentSigchldHandler(int signal) +{ + int pid = 0; + int status; + int options; + + #ifdef TEST + fprintf(stderr, "nxagentSigchldHandler: Going to check the children processes.\n"); + #endif + + options = WNOHANG | WUNTRACED; + + /* + * Try with the pid of the dialog process. + * Leave the other children unaffected. + */ + + if (pid == 0 && nxagentRootlessDialogPid) + { + pid = waitpid(nxagentRootlessDialogPid, &status, options); + + if (pid == -1 && errno == ECHILD) + { + #ifdef WARNING + fprintf(stderr, "nxagentSigchldHandler: Got ECHILD waiting for child %d (Rootless dialog).\n", + nxagentRootlessDialogPid); + #endif + + pid = nxagentRootlessDialogPid = 0; + } + } + + if (pid == 0 && nxagentPulldownDialogPid) + { + pid = waitpid(nxagentPulldownDialogPid, &status, options); + + if (pid == -1 && errno == ECHILD) + { + #ifdef WARNING + fprintf(stderr, "nxagentSigchldHandler: Got ECHILD waiting for child %d (Pulldown dialog).\n", + nxagentPulldownDialogPid); + #endif + + pid = nxagentPulldownDialogPid = 0; + } + } + + if (pid == 0 && nxagentKillDialogPid) + { + pid = waitpid(nxagentKillDialogPid, &status, options); + + if (pid == -1 && errno == ECHILD) + { + #ifdef WARNING + fprintf(stderr, "nxagentSigchldHandler: Got ECHILD waiting for child %d (Kill dialog).\n", + nxagentKillDialogPid); + #endif + + pid = nxagentKillDialogPid = 0; + } + } + + if (pid == 0 && nxagentSuspendDialogPid) + { + pid = waitpid(nxagentSuspendDialogPid, &status, options); + + if (pid == -1 && errno == ECHILD) + { + #ifdef WARNING + fprintf(stderr, "nxagentSigchldHandler: Got ECHILD waiting for child %d (Suspend dialog).\n", + nxagentSuspendDialogPid); + #endif + + pid = nxagentSuspendDialogPid = 0; + } + } + + if (pid == 0 && nxagentFontsReplacementDialogPid) + { + pid = waitpid(nxagentFontsReplacementDialogPid, &status, options); + + if (pid == -1 && errno == ECHILD) + { + #ifdef WARNING + fprintf(stderr, "nxagentSigchldHandler: Got ECHILD waiting for child %d (Fonts replacement).\n", + nxagentFontsReplacementDialogPid); + #endif + + pid = nxagentFontsReplacementDialogPid = 0; + } + } + + if (pid == 0 && nxagentEnableRandRModeDialogPid) + { + pid = waitpid(nxagentEnableRandRModeDialogPid, &status, options); + + if (pid == -1 && errno == ECHILD) + { + #ifdef WARNING + fprintf(stderr, "nxagentSigchldHandler: Got ECHILD waiting for child %d (EnableRandRMode dialog).\n", + nxagentEnableRandRModeDialogPid); + #endif + + pid = nxagentEnableRandRModeDialogPid = 0; + } + } + + if (pid == 0 && nxagentDisableRandRModeDialogPid) + { + pid = waitpid(nxagentDisableRandRModeDialogPid, &status, options); + + if (pid == -1 && errno == ECHILD) + { + #ifdef WARNING + fprintf(stderr, "nxagentSigchldHandler: Got ECHILD waiting for child %d (DisableRandRMode dialog).\n", + nxagentDisableRandRModeDialogPid); + #endif + + pid = nxagentDisableRandRModeDialogPid = 0; + } + } + + if (pid == 0 && nxagentEnableDeferModePid) + { + pid = waitpid(nxagentEnableDeferModePid, &status, options); + + if (pid == -1 && errno == ECHILD) + { + #ifdef WARNING + fprintf(stderr, "nxagentSigchldHandler: Got ECHILD waiting for child %d (EnableDeferMode dialog).\n", + nxagentEnableDeferModePid); + #endif + + pid = nxagentEnableDeferModePid = 0; + } + } + + if (pid == 0 && nxagentDisableDeferModePid) + { + pid = waitpid(nxagentDisableDeferModePid, &status, options); + + if (pid == -1 && errno == ECHILD) + { + #ifdef WARNING + fprintf(stderr, "nxagentSigchldHandler: Got ECHILD waiting for child %d (DisableDeferMode dialog).\n", + nxagentDisableDeferModePid); + #endif + + pid = nxagentDisableDeferModePid = 0; + } + } + + if (pid == -1) + { + FatalError("Got error '%s' waiting for the child.\n", strerror(errno)); + } + + if (pid > 0) + { + if (WIFSTOPPED(status)) + { + #ifdef WARNING + fprintf(stderr, "nxagentSigchldHandler: Child process [%d] was stopped " + "with signal [%d].\n", pid, (WSTOPSIG(status))); + #endif + } + else + { + #ifdef TEST + + if (WIFEXITED(status)) + { + fprintf(stderr, "nxagentSigchldHandler: Child process [%d] exited " + "with status [%d].\n", pid, (WEXITSTATUS(status))); + } + else if (WIFSIGNALED(status)) + { + fprintf(stderr, "nxagentSigchldHandler: Child process [%d] died " + "because of signal [%d].\n", pid, (WTERMSIG(status))); + } + + #endif + + nxagentResetDialog(pid); + } + } + else if (pid == 0) + { + #ifdef TEST + fprintf(stderr, "nxagentSigchldHandler: Forwarding the signal to the NX transport.\n"); + #endif + + NXTransSignal(SIGCHLD, NX_SIGNAL_RAISE); + } + + return; +} + +Display *nxagentInternalOpenDisplay(char *display) +{ + Display *newDisplay; + + struct sigaction oldAction; + struct sigaction newAction; + + int result; + + #ifdef SMART_SCHEDULE + + /* + * Stop the smart schedule timer since + * it uses SIGALRM as we do. + */ + + nxagentStopTimer(); + + #endif + + /* + * Install the handler rejecting a possible + * loopback connection. + */ +/* +FIXME: Should print a warning if the user tries to let + the agent impersonate the same display as the + display where the agent is supposed to connect. + We actually handle this by means of RejectWell- + KnownSockets() but without giving to the user + a friendly explaination for the error. +*/ + + newAction.sa_handler = nxagentRejectConnection; + + sigfillset(&newAction.sa_mask); + + newAction.sa_flags = 0; + + while (((result = sigaction(SIGALRM, &newAction, + &oldAction)) == -1) && (errno == EINTR)); + + if (result == -1) + { + FatalError("Can't set alarm for rejecting connections."); + } + + alarm(10); + + #ifdef TEST + fprintf(stderr, "nxagentInternalOpenDisplay: Going to open the display [%s].\n", + display); + #endif + + newDisplay = XOpenDisplay(display); + + alarm(0); + + while (((result = sigaction(SIGALRM, &oldAction, + NULL)) == -1) && (errno == EINTR)); + + if (result == -1) + { + FatalError("Can't restore alarm for rejecting connections."); + } + + #ifdef TEST + fprintf(stderr, "nxagentInternalOpenDisplay: Setting the NX flush policy to immediate.\n"); + #endif + + NXSetDisplayPolicy(nxagentDisplay, NXPolicyImmediate); + + #ifdef TEST + fprintf(stderr, "nxagentInternalOpenDisplay: Function returned display at [%p].\n", + (void *) newDisplay); + #endif + + return newDisplay; +} + +static void nxagentDisplayBlockHandler(Display *display, int reason) +{ + if (nxagentDisplay != NULL) + { + /* + * Don't allow the smart schedule to + * interrupt the agent while waiting + * for the remote display. + */ + + #ifdef SMART_SCHEDULE + + #ifdef DEBUG + fprintf(stderr, "nxagentDisplayBlockHandler: BLOCK! Stopping the smart schedule timer.\n"); + #endif + + nxagentStopTimer(); + + #endif + + if (reason == NXBlockRead) + { + #ifdef DEBUG + fprintf(stderr, "nxagentDisplayBlockHandler: BLOCK! Display is blocking for [read].\n"); + #endif + } + else + { + #ifdef DEBUG + fprintf(stderr, "nxagentDisplayBlockHandler: BLOCK! Display is blocking for [write].\n"); + #endif + + nxagentBlocking = 1; + + #ifdef SMART_SCHEDULE + + if (SmartScheduleDisable == 1) + { + + #endif + + /* + * Let the dispatch attend the next + * client. + */ + + #ifdef DEBUG + fprintf(stderr, "nxagentDisplayBlockHandler: BLOCK! Yielding with agent blocked.\n"); + #endif + + nxagentDispatch.start = GetTimeInMillis(); + + nxagentDispatch.in = nxagentBytesIn; + nxagentDispatch.out = nxagentBytesOut; + + #ifdef SMART_SCHEDULE + + } + + #endif + + /* + * Give a chance to the next client. + */ + + isItTimeToYield = 1; + } + } +} + +static void nxagentDisplayWriteHandler(Display *display, int length) +{ + if (nxagentDisplay != NULL) + { + #ifdef TEST + fprintf(stderr, "nxagentDisplayWriteHandler: WRITE! Called with [%d] bytes written.\n", + length); + #endif + + /* + * Notify the dispatch handler. + */ + + nxagentDispatchHandler(NULL, 0, length); + + if (nxagentOption(LinkType) == LINK_TYPE_NONE) + { + nxagentFlush = GetTimeInMillis(); + } + } +} + +static void nxagentDisplayFlushHandler(Display *display, int length) +{ + if (nxagentDisplay != NULL) + { + #ifdef TEST + fprintf(stderr, "nxagentDisplayFlushHandler: FLUSH! Called with [%d] bytes flushed.\n", + length); + #endif + + nxagentCongestion = NXDisplayCongestion(nxagentDisplay); + + #ifdef TEST + fprintf(stderr, "nxagentDisplayFlushHandler: FLUSH! Current congestion level is [%d].\n", + nxagentCongestion); + #endif + + if (nxagentOption(LinkType) != LINK_TYPE_NONE) + { + nxagentFlush = GetTimeInMillis(); + } + } +} + +static int nxagentDisplayErrorPredicate(Display *display, int error) +{ + #ifdef TEST + fprintf(stderr, "nxagentDisplayErrorPredicate: CHECK! Error is [%d] with [%d][%d][%d][%d][%d].\n", + ((error == 1) || (dispatchException & DE_RESET) != 0 || + (dispatchException & DE_TERMINATE) != 0 || nxagentException.sigHup > 0 || + nxagentException.ioError > 0), error, (dispatchException & DE_RESET) != 0, + (dispatchException & DE_TERMINATE), nxagentException.sigHup > 0, + nxagentException.ioError > 0); + #endif + + if (error == 0) + { + if ((dispatchException & DE_RESET) != 0 || + (dispatchException & DE_TERMINATE)) + { + return 1; + } + else if (nxagentException.sigHup > 0 || + nxagentException.ioError > 0) + { + NXForceDisplayError(display); + + return 1; + } + } + + return error; +} + +void nxagentInstallDisplayHandlers() +{ + /* + * If the display was already opened, be sure + * all structures are freed. + */ + + nxagentResetDisplayHandlers(); + + /* + * We want the Xlib I/O error handler to return, + * instead of quitting the application. Using + * setjmp()/longjmp() leaves the door open to + * unexpected bugs when dealing with interaction + * with the other X server layers. + */ + + NXHandleDisplayError(1); + + NXSetDisplayBlockHandler(nxagentDisplayBlockHandler); + + NXSetDisplayWriteHandler(nxagentDisplayWriteHandler); + + NXSetDisplayFlushHandler(nxagentDisplayFlushHandler, NULL); + + /* + * Override the default Xlib error handler. + */ + + XSetIOErrorHandler(nxagentIOErrorHandler); + + /* + * Let Xlib become aware of our interrupts. In theory + * we don't need to have the error handler installed + * during the normal operations and could simply let + * the dispatcher handle the interrupts. In practice + * it's better to have Xlib invalidating the display + * as soon as possible rather than incurring in the + * risk of entering a loop that doesn't care checking + * the display errors explicitly. + */ + + #ifdef TEST + fprintf(stderr, "nxagentInstallDisplayHandlers: Installing the error function predicate.\n"); + #endif + + NXSetDisplayErrorPredicate(nxagentDisplayErrorPredicate); +} + +void nxagentPostInstallDisplayHandlers() +{ + /* + * This is executed after having opened the + * display, once we know the display address. + */ + + if (nxagentDisplay != NULL) + { + #ifdef TEST + fprintf(stderr, "nxagentPostInstallDisplayHandlers: Initializing the NX display internals.\n"); + #endif + + NXInitDisplay(nxagentDisplay); +/* +FIXME: What is the most appropriate number of elements? + + NXInitCache(nxagentDisplay, 128); +*/ + NXInitCache(nxagentDisplay, 256); + + NXSetDisplayFlushHandler(nxagentDisplayFlushHandler, nxagentDisplay); + } + + /* + * Handler for the Xlib protocol errors. + */ + + XSetErrorHandler(nxagentErrorHandler); +} + +void nxagentResetDisplayHandlers() +{ + if (nxagentDisplay != NULL) + { + /* + * Free the internal nxcompext + * structures. + */ + + NXResetDisplay(nxagentDisplay); + + /* + * Remove the display descriptor + * from the listened sockets. + */ + + nxagentRemoveXConnection(); + + /* + * Restart the suspended clients. + */ + + nxagentWakeupByReconnect(); + + nxagentReleaseAllSplits(); + } + + /* + * Reset the display to a healty state. + */ + + nxagentBuffer = 0; + nxagentBlocking = 0; + nxagentCongestion = 0; + + /* + * Reset the counter of synchronization + * requests pending. + */ + + nxagentTokens.soft = 0; + nxagentTokens.hard = 0; + nxagentTokens.pending = 0; + + /* + * Reset the current dispatch information. + */ + + nxagentDispatch.client = UNDEFINED; + nxagentDispatch.in = 0; + nxagentDispatch.out = 0; + nxagentDispatch.start = 0; +} + +void nxagentInstallSignalHandlers() +{ + #ifdef TEST + fprintf(stderr, "nxagentInstallSignalHandlers: Installing the agent signal handlers.\n"); + #endif + + /* + * Keep the default X server's handlers for + * SIGINT and SIGTERM and restore the other + * signals of interest to our defaults. + */ + + struct sigaction newAction; + + int result; + + /* + * By default nxcomp installs its signal handlers. + * We need to ensure that SIGUSR1 and SIGUSR2 are + * ignored if the NX transport is not running. + */ + + newAction.sa_handler = nxagentSigusrHandler; + + sigfillset(&newAction.sa_mask); + + newAction.sa_flags = 0; + + while (((result = sigaction(SIGUSR1, &newAction, + NULL)) == -1) && (errno == EINTR)); + + if (result == -1) + { + FatalError("Can't set the handler for user signal 1."); + } + + while (((result = sigaction(SIGUSR2, &newAction, + NULL)) == -1) && (errno == EINTR)); + + if (result == -1) + { + FatalError("Can't set the handler for user signal 2."); + } + + /* + * Reset the SIGALRM to the default. + */ + + #ifdef SMART_SCHEDULE + + nxagentStopTimer(); + + #endif + + newAction.sa_handler = SIG_DFL; + + sigfillset(&newAction.sa_mask); + + while (((result = sigaction(SIGALRM, &newAction, + NULL)) == -1) && (errno == EINTR)); + + if (result == -1) + { + FatalError("Can't set the handler for alarm signal."); + } + + #ifdef SMART_SCHEDULE + + /* + * Let the smart schedule set the SIGALRM + * handler again. + */ + + nxagentInitTimer(); + + #endif + + /* + * Install our own handler for the SIGHUP. + */ + + newAction.sa_handler = nxagentSighupHandler; + + sigfillset(&newAction.sa_mask); + + newAction.sa_flags = 0; + + while (((result = sigaction(SIGHUP, &newAction, + NULL)) == -1) && (errno == EINTR)); + + if (result == -1) + { + FatalError("Can't set the handler for session suspend."); + } + + /* + * We need to be notified about our children. + */ + + newAction.sa_handler = nxagentSigchldHandler; + + sigfillset(&newAction.sa_mask); + + newAction.sa_flags = 0; + + while (((result = sigaction(SIGCHLD, &newAction, + NULL)) == -1) && (errno == EINTR)); + + if (result == -1) + { + FatalError("Can't set the handler for children."); + } +} + +void nxagentPostInstallSignalHandlers() +{ + #ifdef TEST + fprintf(stderr, "nxagentPostInstallSignalHandlers: Dealing with the proxy signal handlers.\n"); + #endif + + /* + * Reconfigure our signal handlers to work well + * with the NX transport. + * + * Let our handlers manage the SIGINT and SIGTERM. + * The following calls will tell the NX transport + * to restore the old handlers (those originally + * installed by us or the X server). + */ + + NXTransSignal(SIGINT, NX_SIGNAL_DISABLE); + NXTransSignal(SIGTERM, NX_SIGNAL_DISABLE); + + /* + * Also tell the proxy to ignore the SIGHUP. + */ + + NXTransSignal(SIGHUP, NX_SIGNAL_DISABLE); + + /* + * Both the proxy and the agent need to catch + * their children, so we'll have to send the + * signal to transport. + */ + + NXTransSignal(SIGCHLD, NX_SIGNAL_DISABLE); + + /* + * Let the NX transport take care of SIGUSR1 + * and SIGUSR2. + */ +} + +void nxagentResetSignalHandlers() +{ + struct sigaction newAction; + + int result; + + /* + * Reset the signal handlers + * to a well known state. + */ + + #ifdef TEST + fprintf(stderr, "nxagentResetSignalHandlers: Resetting the agent the signal handlers.\n"); + #endif + + /* + * Reset the SIGALRM to the default. + */ + + #ifdef SMART_SCHEDULE + + nxagentStopTimer(); + + #endif + + newAction.sa_handler = SIG_DFL; + + sigfillset(&newAction.sa_mask); + + while (((result = sigaction(SIGALRM, &newAction, + NULL)) == -1) && (errno == EINTR)); + + if (result == -1) + { + FatalError("Can't set the handler for alarm signal."); + } + + #ifdef SMART_SCHEDULE + + /* + * Let the smart schedule set the SIGALRM + * handler again. + */ + + nxagentInitTimer(); + + #endif +} + +void nxagentOpenDisplay(int argc, char *argv[]) +{ + int i; + + if (!nxagentDoFullGeneration) return; + + #ifdef NXAGENT_TIMESTAMP + + startTime = GetTimeInMillis(); + + fprintf(stderr, "Display: Opening the display on real X server with time [%d] ms.\n", + GetTimeInMillis() - startTime); + + #endif + + /* + * Initialize the reconnector only in the case + * of persistent sessions. + */ + + if (nxagentOption(Persistent)) + { + nxagentInitReconnector(); + } + + if (*nxagentDisplayName == '\0') + { + strncpy(nxagentDisplayName, XDisplayName(NULL), 1023); + + nxagentDisplayName[1023] = '\0'; + } + + nxagentCloseDisplay(); + + nxagentInstallSignalHandlers(); + + nxagentInstallDisplayHandlers(); + + nxagentDisplay = nxagentInternalOpenDisplay(nxagentDisplayName); + + nxagentPostInstallSignalHandlers(); + + nxagentPostInstallDisplayHandlers(); + + if (nxagentDisplay == NULL) + { +/* +FIXME: The agent should never exit the program with a FatalError() + but rather use a specific function that may eventually call + FatalError() on its turn. +*/ + FatalError("Unable to open display '%s'.\n", nxagentDisplayName); + } + + nxagentXConnectionNumber = XConnectionNumber(nxagentDisplay); + + #ifdef TEST + fprintf(stderr, "nxagentOpenDisplay: Display image order is [%d] bitmap order is [%d].\n", + ImageByteOrder(nxagentDisplay), BitmapBitOrder(nxagentDisplay)); + + fprintf(stderr, "nxagentOpenDisplay: Display scanline unit is [%d] scanline pad is [%d].\n", + BitmapUnit(nxagentDisplay), BitmapPad(nxagentDisplay)); + #endif + + #ifdef WATCH + + fprintf(stderr, "nxagentOpenDisplay: Watchpoint 1.\n"); + +/* +Reply Total Cached Bits In Bits Out Bits/Reply Ratio +------- ----- ------ ------- -------- ---------- ----- +#1 U 1 1 256 bits (0 KB) -> 150 bits (0 KB) -> 256/1 -> 150/1 = 1.707:1 +#20 1 1 119104 bits (15 KB) -> 28 bits (0 KB) -> 119104/1 -> 28/1 = 4253.714:1 +#98 2 512 bits (0 KB) -> 84 bits (0 KB) -> 256/1 -> 42/1 = 6.095:1 +*/ + + sleep(60); + + #endif + + #ifdef NXAGENT_TIMESTAMP + + fprintf(stderr, "Display: Display on real X server opened with time [%d] ms.\n", + GetTimeInMillis() - startTime); + + #endif + + nxagentUseNXTrans = + nxagentPostProcessArgs(nxagentDisplayName, nxagentDisplay, + DefaultScreenOfDisplay(nxagentDisplay)); + + /* + * Processing the arguments all the timeouts + * have been set. Now we have to change the + * screen-saver timeout. + */ + + nxagentSetScreenSaverTime(); + + nxagentInitVisuals(); + + nxagentNumDefaultColormaps = nxagentNumVisuals; + nxagentDefaultColormaps = (Colormap *)xalloc(nxagentNumDefaultColormaps * + sizeof(Colormap)); + + for (i = 0; i < nxagentNumDefaultColormaps; i++) + { + nxagentDefaultColormaps[i] = XCreateColormap(nxagentDisplay, + DefaultRootWindow(nxagentDisplay), + nxagentVisuals[i].visual, + AllocNone); + } + + #ifdef WATCH + + fprintf(stderr, "nxagentOpenDisplay: Watchpoint 4.\n"); + +/* +Reply Total Cached Bits In Bits Out Bits/Reply Ratio +------- ----- ------ ------- -------- ---------- ----- +N/A +*/ + + sleep(30); + + #endif + + nxagentBlackPixel = BlackPixel(nxagentDisplay, DefaultScreen(nxagentDisplay)); + nxagentWhitePixel = WhitePixel(nxagentDisplay, DefaultScreen(nxagentDisplay)); + + #ifdef WATCH + + fprintf(stderr, "nxagentOpenDisplay: Watchpoint 5.\n"); + +/* +Reply Total Cached Bits In Bits Out Bits/Reply Ratio +------- ----- ------ ------- -------- ---------- ----- +N/A +*/ + + sleep(30); + + #endif + + /* + * Initialize the agent's event mask that will be requested + * for the root and all the top level windows. If the nested + * window is a child of an existing window, we will need to + * receive StructureNotify events. If we are going to manage + * the changes in root window's visibility we'll also need + * VisibilityChange events. + */ + +/* +FIXME: Use of nxagentParentWindow is strongly deprecated. + We need also to clarify which events are selected + in the diferent operating modes. +*/ + + nxagentInitDefaultEventMask(); + + /* + * Initialize the pixmap depths and formats. + */ + + nxagentInitDepths(); + + nxagentInitPixmapFormats(); + + /* + * Create a pixmap for each depth matching the + * local supported formats with format available + * on the remote display. + */ + + nxagentSetDefaultDrawables(); + + #ifdef RENDER + if (nxagentRenderEnable) + { + nxagentRenderExtensionInit(); + } + #endif + + /* + * This GC is referenced in Cursor.c. It can be + * probably removed. + */ + + nxagentBitmapGC = XCreateGC(nxagentDisplay, nxagentDefaultDrawables[1], 0L, NULL); + + /* + * Note that this "confine window" is useless at the + * moment as we reimplement nxagentConstrainCursor() + * to skip the "constrain" stuff. + */ + + #ifdef TEST + fprintf(stderr, "nxagentOpenDisplay: Going to create agent's confine window.\n"); + #endif + + nxagentConfineWindow = XCreateWindow(nxagentDisplay, + DefaultRootWindow(nxagentDisplay), + 0, 0, 1, 1, 0, 0, + InputOnly, + CopyFromParent, + 0L, NULL); + + #ifdef TEST + fprintf(stderr, "nxagentOpenDisplay: Created agent's confine window with id [%ld].\n", + nxagentConfineWindow); + #endif + + if (!(nxagentUserGeometry.flag & XValue)) + { + nxagentChangeOption(RootX, 0); + } + + if (!(nxagentUserGeometry.flag & YValue)) + { + nxagentChangeOption(RootY, 0); + } + + if (nxagentParentWindow == 0) + { + if (!(nxagentUserGeometry.flag & WidthValue)) + { + if (nxagentOption(Fullscreen)) + { + nxagentChangeOption(RootWidth, DisplayWidth(nxagentDisplay, DefaultScreen(nxagentDisplay))); + } + else + { + nxagentChangeOption(RootWidth, 3 * DisplayWidth(nxagentDisplay, + DefaultScreen(nxagentDisplay)) / 4); + } + } + + if (!(nxagentUserGeometry.flag & HeightValue)) + { + if (nxagentOption(Fullscreen)) + { + nxagentChangeOption(RootHeight, DisplayHeight(nxagentDisplay, DefaultScreen(nxagentDisplay))); + } + else + { + nxagentChangeOption(RootHeight, 3 * DisplayHeight(nxagentDisplay, + DefaultScreen(nxagentDisplay)) / 4); + } + } + } + + if (!nxagentUserBorderWidth) + { + nxagentChangeOption(BorderWidth, 1); + } + + nxagentLogoDepth = DefaultDepth(nxagentDisplay, + DefaultScreen(nxagentDisplay) + ); + + pV = nxagentVisuals[nxagentDefaultVisualIndex]; + + r = pV.red_mask; + g = pV.green_mask; + b = pV.blue_mask; + + if (!pV.red_mask || !pV.green_mask || !pV.blue_mask) + { + nxagentLogoBlack = 0x000000; + nxagentLogoRed = 0xff0000; + nxagentLogoWhite = 0xffffff; + } + else + { + for (or=0, off=0x800000; (r&(off>>or)) == 0; or++); + for (og=0, off=0x800000; (g&(off>>og)) == 0; og++); + for (ob=0, off=0x800000; (b&(off>>ob)) == 0; ob++); + + nxagentLogoRed = nxagentLogoColor(0xff0000); + nxagentLogoBlack = nxagentLogoColor(0x000000); + nxagentLogoWhite = 0xffffff; + } + + #ifdef WATCH + + fprintf(stderr, "nxagentOpenDisplay: Watchpoint 5.1.\n"); + +/* +Reply Total Cached Bits In Bits Out Bits/Reply Ratio +------- ----- ------ ------- -------- ---------- ----- +N/A +*/ + + sleep(30); + + #endif + + useXpmIcon = nxagentMakeIcon(nxagentDisplay, &nxagentIconPixmap, &nxagentIconShape); + + #ifdef WATCH + + fprintf(stderr, "nxagentOpenDisplay: Watchpoint 5.2.\n"); + +/* +Reply Total Cached Bits In Bits Out Bits/Reply Ratio +------- ----- ------ ------- -------- ---------- ----- +#84 2 512 bits (0 KB) -> 76 bits (0 KB) -> 256/1 -> 38/1 = 6.737:1 +*/ + + sleep(30); + + #endif + + #ifdef WATCH + + fprintf(stderr, "nxagentOpenDisplay: Watchpoint 6.\n"); + +/* +Reply Total Cached Bits In Bits Out Bits/Reply Ratio +------- ----- ------ ------- -------- ---------- ----- +N/A +*/ + + sleep(30); + + #endif + + #ifdef NXAGENT_TIMESTAMP + + fprintf(stderr, "Display: Open of the display finished with time [%d] ms.\n", + GetTimeInMillis() - startTime); + + #endif + + if (nxagentOption(Persistent)) + { + reconnectDisplayState = EVERYTHING_DONE; + } +} + +void nxagentSetDefaultVisual(void) +{ + XVisualInfo vi; + + int i; + + if (nxagentUserDefaultClass || nxagentUserDefaultDepth) + { + nxagentDefaultVisualIndex = UNDEFINED; + + for (i = 0; i < nxagentNumVisuals; i++) + { + if ((!nxagentUserDefaultClass || + nxagentVisuals[i].class == nxagentDefaultClass) + && + (!nxagentUserDefaultDepth || + nxagentVisuals[i].depth == nxagentDefaultDepth)) + { + nxagentDefaultVisualIndex = i; + + break; + } + } + + if (nxagentDefaultVisualIndex == UNDEFINED) + { + FatalError("Unable to find desired default visual.\n"); + } + } + else + { + vi.visualid = XVisualIDFromVisual(DefaultVisual(nxagentDisplay, + DefaultScreen(nxagentDisplay))); + nxagentDefaultVisualIndex = 0; + + for (i = 0; i < nxagentNumVisuals; i++) + { + if (vi.visualid == nxagentVisuals[i].visualid) + { + nxagentDefaultVisualIndex = i; + } + } + } +} + +void nxagentInitVisuals(void) +{ + XVisualInfo vi; + XVisualInfo *viList = NULL; + + long mask; + int i, viNumList; + + mask = VisualScreenMask; + vi.screen = DefaultScreen(nxagentDisplay); + vi.depth = DefaultDepth(nxagentDisplay, DefaultScreen(nxagentDisplay)); + viList = XGetVisualInfo(nxagentDisplay, mask, &vi, &viNumList); + nxagentVisuals = (XVisualInfo *) malloc(viNumList * sizeof(XVisualInfo)); + nxagentNumVisuals = 0; + + for (i = 0; i < viNumList; i++) + { + if (viList[i].depth == vi.depth) + { + if (nxagentVisuals != NULL) + { + memcpy(nxagentVisuals + nxagentNumVisuals, viList + i, sizeof(XVisualInfo)); + } + + #ifdef DEBUG + fprintf(stderr, "nxagentInitVisuals: Visual:\n"); + fprintf(stderr, "\tdepth = %d\n", nxagentVisuals[nxagentNumVisuals].depth); + fprintf(stderr, "\tclass = %d\n", nxagentVisuals[nxagentNumVisuals].class); + fprintf(stderr, "\tmask = (%lu,%lu,%lu)\n", + nxagentVisuals[nxagentNumVisuals].red_mask, + nxagentVisuals[nxagentNumVisuals].green_mask, + nxagentVisuals[nxagentNumVisuals].blue_mask); + fprintf(stderr, "\tcolormap size = %d\n", nxagentVisuals[nxagentNumVisuals].colormap_size); + fprintf(stderr, "\tbits_per_rgb = %d\n", nxagentVisuals[nxagentNumVisuals].bits_per_rgb); + #endif + + nxagentNumVisuals++; + } + } + + if (nxagentVisuals != NULL) + { + nxagentVisuals = (XVisualInfo *) realloc(nxagentVisuals, + nxagentNumVisuals * sizeof(XVisualInfo)); + } + + XFree(viList); + + if (nxagentNumVisuals == 0 || nxagentVisuals == NULL) + { + FatalError("Unable to find any visuals.\n"); + } + + nxagentSetDefaultVisual(); +} + +void nxagentInitDepths() +{ + #ifdef TEST + int i; + #endif + + nxagentDepths = XListDepths(nxagentDisplay, DefaultScreen(nxagentDisplay), + &nxagentNumDepths); + + if (nxagentDepths == NULL) + { + #ifdef PANIC + fprintf(stderr, "nxagentInitDepths: PANIC! Failed to get available depths.\n"); + #endif + + FatalError("Failed to get available depths and pixmap formats."); + } + #ifdef TEST + else + { + fprintf(stderr, "nxagentInitDepths: Got [%d] available depths:\n", + nxagentNumDepths); + + for (i = 0; i < nxagentNumDepths; i++) + { + fprintf(stderr, " [%d]", nxagentDepths[i]); + } + + fprintf(stderr, ".\n"); + } + #endif +} + +void nxagentInitPixmapFormats() +{ + int i, j; + int depth; + + /* + * Formats are created with no care of which are supported + * on the real display. Creating only formats supported + * by the remote end makes troublesome handling migration + * of session from a display to another. + */ + + nxagentNumPixmapFormats = 0; + +/* +XXX: Some X server doesn't list 1 among available depths... +*/ + + nxagentPixmapFormats = xalloc((nxagentNumDepths + 1) * sizeof(XPixmapFormatValues)); + + for (i = 1; i <= MAXDEPTH; i++) + { + depth = 0; + + if (i == 1) + { + depth = 1; + } + else + { + for (j = 0; j < nxagentNumDepths; j++) + { + if (nxagentDepths[j] == i) + { + depth = i; + + break; + } + } + } + + if (depth != 0) + { + if (nxagentNumPixmapFormats >= MAXFORMATS) + { + FatalError("nxagentInitPixmapFormats: MAXFORMATS is too small for this server.\n"); + } + + nxagentPixmapFormats[nxagentNumPixmapFormats].depth = depth; + nxagentPixmapFormats[nxagentNumPixmapFormats].bits_per_pixel = nxagentBitsPerPixel(depth); + nxagentPixmapFormats[nxagentNumPixmapFormats].scanline_pad = BITMAP_SCANLINE_PAD; + + #ifdef TEST + fprintf(stderr, "nxagentInitPixmapFormats: Set format [%d] to depth [%d] " + "bits per pixel [%d] scanline pad [%d].\n", nxagentNumPixmapFormats, + depth, nxagentPixmapFormats[nxagentNumPixmapFormats].bits_per_pixel, + BITMAP_SCANLINE_PAD); + #endif + + nxagentNumPixmapFormats++; + } + } + + nxagentRemotePixmapFormats = XListPixmapFormats(nxagentDisplay, &nxagentRemoteNumPixmapFormats); + + if (nxagentRemotePixmapFormats == NULL) + { + #ifdef WARNING + fprintf(stderr, "nxagentInitPixmapFormats: WARNING! Failed to get available remote pixmap formats.\n"); + #endif + } + #ifdef TEST + else + { + fprintf(stderr, "nxagentInitPixmapFormats: Got [%d] available remote pixmap formats:\n", + nxagentRemoteNumPixmapFormats); + + for (i = 0; i < nxagentRemoteNumPixmapFormats; i++) + { + fprintf(stderr, "nxagentInitPixmapFormats: Remote pixmap format [%d]: depth [%d] " + "bits_per_pixel [%d] scanline_pad [%d].\n", i, nxagentRemotePixmapFormats[i].depth, + nxagentRemotePixmapFormats[i].bits_per_pixel, nxagentRemotePixmapFormats[i].scanline_pad); + } + } + #endif + + nxagentCheckForPixmapFormatsCompatibility(); +} + +void nxagentSetDefaultDrawables() +{ + int i, j; + + for (i = 0; i <= MAXDEPTH; i++) + { + nxagentDefaultDrawables[i] = None; + } + + for (i = 0; i < nxagentNumPixmapFormats; i++) + { + #ifdef TEST + fprintf(stderr, "nxagentSetDefaultDrawables: Checking remote pixmap format [%d] with depth [%d] " + "bits per pixel [%d] scanline pad [%d].\n", i, nxagentPixmapFormats[i].depth, + nxagentPixmapFormats[i].bits_per_pixel, nxagentPixmapFormats[i].scanline_pad); + #endif + + if (nxagentPixmapFormats[i].depth == 24) + { + if (nxagentPixmapFormats[i].bits_per_pixel == 24) + { + #ifdef TEST + fprintf(stderr, "nxagentSetDefaultDrawables: WARNING! Assuming remote pixmap " + "format [%d] as true 24 bits.\n", i); + #endif + + nxagentTrue24 = True; + } + } + + for (j = 0; j < nxagentNumDepths; j++) + { + #ifdef TEST + fprintf(stderr, "nxagentSetDefaultDrawables: Checking depth at index [%d] with pixmap depth [%d] " + "and display depth [%d].\n", j, nxagentPixmapFormats[i].depth, nxagentDepths[j]); + #endif + + if ((nxagentPixmapFormats[i].depth == 1 || + nxagentPixmapFormats[i].depth == nxagentDepths[j]) && + nxagentDefaultDrawables[nxagentPixmapFormats[i].depth] == None) + { + nxagentDefaultDrawables[nxagentPixmapFormats[i].depth] = + XCreatePixmap(nxagentDisplay, DefaultRootWindow(nxagentDisplay), + 1, 1, nxagentPixmapFormats[i].depth); + + #ifdef TEST + fprintf(stderr, "nxagentSetDefaultDrawables: Created default drawable [%lu] for depth [%d].\n", + nxagentDefaultDrawables[nxagentPixmapFormats[i].depth], nxagentPixmapFormats[i].depth); + #endif + } + } + + if (nxagentDefaultDrawables[nxagentPixmapFormats[i].depth] == None) + { + #ifdef TEST + fprintf(stderr, "nxagentSetDefaultDrawables: WARNING! Forcing default drawable for depth [%d].\n", + nxagentPixmapFormats[i].depth); + #endif + + nxagentDefaultDrawables[nxagentPixmapFormats[i].depth] = + XCreatePixmap(nxagentDisplay, DefaultRootWindow(nxagentDisplay), + 1, 1, nxagentPixmapFormats[i].depth); + + #ifdef TEST + fprintf(stderr, "nxagentSetDefaultDrawables: Created default drawable [%lu] for depth [%d].\n", + nxagentDefaultDrawables[nxagentPixmapFormats[i].depth], nxagentPixmapFormats[i].depth); + #endif + } + } +} + +void nxagentCloseDisplay() +{ + #ifdef TEST + fprintf(stderr, "nxagentCloseDisplay: Called with full generation [%d] and display [%p].\n", + nxagentDoFullGeneration, (void *) nxagentDisplay); + #endif + + if (nxagentDoFullGeneration == 0 || + nxagentDisplay == NULL) + { + return; + } + + /* + * If nxagentDoFullGeneration is true, all + * the X resources will be destroyed upon + * closing the display connection, so there + * is no real need to generate additional + * traffic + */ + + xfree(nxagentDefaultColormaps); + nxagentDefaultColormaps = NULL; + + XFree(nxagentVisuals); + nxagentVisuals = NULL; + + xfree(nxagentDepths); + nxagentDepths = NULL; + + XFree(nxagentPixmapFormats); + nxagentPixmapFormats = NULL; + + XFree(nxagentRemotePixmapFormats); + nxagentRemotePixmapFormats = NULL; + + nxagentFreeFontCache(); +/* +FIXME: Is this needed? + + nxagentFreeFontMatchStuff(); +*/ + + /* + * Free the image cache. This is useful + * for detecting memory leaks. + */ + + if (nxagentDisplay != NULL) + { + NXFreeCache(nxagentDisplay); + + NXResetDisplay(nxagentDisplay); + } + + /* + * Kill all the running dialogs. + */ + + nxagentTerminateDialogs(); + + #ifdef TEST + fprintf(stderr, "nxagentCloseDisplay: Setting the display to NULL.\n"); + #endif + + XCloseDisplay(nxagentDisplay); + + nxagentDisplay = NULL; +} + +Bool nxagentMakeIcon(Display *display, Pixmap *nxIcon, Pixmap *nxMask) +{ + char *env_path = getenv("PATH"); + int lenght_env_path = 0; + char icon_filename [256]; + char default_path [256]; + char *icon_path = malloc( strlen(env_path) + sizeof(icon_filename) ); + FILE *icon_fp; + int status; + Bool success = False; + XlibPixmap IconPixmap; + XlibPixmap IconShape; + + if (env_path == NULL) + lenght_env_path = 0; + else + lenght_env_path = strlen(env_path) + 1; + strncpy(icon_filename, "", 255); + strncpy(default_path, "", 255); + + strcat(icon_filename, NXAGENT_ICON_NAME); + strcat(default_path,"/usr/NX/share/images/"); + strcat(default_path,icon_filename); + + if ((icon_fp = fopen(default_path, "r")) == NULL) + { + char *s; + char *temp_path = malloc(lenght_env_path + strlen(icon_filename) ); + char *temp_path1 = malloc(lenght_env_path + strlen(icon_filename) ); + + strncpy(temp_path, env_path, strlen(env_path)); + strncpy(temp_path1, "", lenght_env_path + strlen(icon_filename) ); + + while (strlen(temp_path) > 0) + { + s = strpbrk (temp_path, ":"); + if (s == NULL) break; + + strncpy (temp_path1, temp_path , strlen(temp_path) - strlen(s) ); + strncat (temp_path1, "/", 1); + strncat (temp_path1, icon_filename, strlen(icon_filename)); + if ((icon_fp = fopen(temp_path1, "r")) != NULL) + { + fclose (icon_fp); + success = True; + strcpy(icon_path,temp_path1); + break; + } + strncpy(temp_path1, "", lenght_env_path + strlen(icon_filename) ); + strncpy(temp_path1, s + 1, strlen(s)-1); + strncpy(temp_path, "", lenght_env_path + strlen(icon_filename) ); + strcpy(temp_path, temp_path1 ); + strncpy(temp_path1, "", lenght_env_path + strlen(icon_filename) ); + } + free(temp_path); + free(temp_path1); + } + else + { + fclose (icon_fp); + success = True; + strcpy(icon_path, default_path); + } + + if (success) + { + status = XpmReadFileToPixmap(display, + DefaultRootWindow(display), + icon_path, + &IconPixmap, + &IconShape, + NULL); + + if (status != XpmSuccess) + { + #ifdef TEST + fprintf(stderr, "nxagentMakeIcon: Xpm operation failed with error '%s'.\n", + XpmGetErrorString(status)); + #endif + + success = False; + } + } + + if (!success) + { + status = XpmCreatePixmapFromData(display, + DefaultRootWindow(display), + nxagentIconData, + &IconPixmap, + &IconShape, + NULL); + + if (status != XpmSuccess) + { + #ifdef TEST + fprintf(stderr, "nxagentMakeIcon: Xpm operation failed with error '%s'.\n", + XpmGetErrorString(status)); + #endif + + success = False; + } + else + { + success = True; + } + } + + free(icon_path); + + *nxIcon = IconPixmap; + *nxMask = IconShape; + + return success; +} + +Bool nxagentXServerGeometryChanged() +{ + return (WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) != + WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplayBackup))) || + (HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) != + HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplayBackup))); +} + +void nxagentBackupDisplayInfo(void) +{ + if (nxagentDisplayInfoSaved) + { + return; + } + + /* + * Since we need the display structure + * in order to behave correctly when no X + * connection is available, we must always + * have a good display record. + * It can be discarded only when a new X + * connection is available, so we store it + * in order to destroy whenever the recon- + * nection succed. + */ + + nxagentDisplayBackup = nxagentDisplay; + nxagentBitmapGCBackup = nxagentBitmapGC; + nxagentDepthsRecBackup = nxagentDepths; + nxagentNumDepthsRecBackup = nxagentNumDepths; + nxagentNumDefaultColormapsRecBackup = nxagentNumDefaultColormaps; + nxagentVisualsRecBackup = nxagentVisuals; + nxagentNumVisualsRecBackup = nxagentNumVisuals; + if (nxagentVisualHasBeenIgnored) + { + xfree(nxagentVisualHasBeenIgnored); + nxagentVisualHasBeenIgnored = NULL; + } + nxagentVisualHasBeenIgnored = xalloc(nxagentNumVisuals * sizeof(Bool)); + nxagentDefaultDepthRecBackup = DefaultDepth(nxagentDisplay, DefaultScreen(nxagentDisplay)); + nxagentDisplayWidthRecBackup = DisplayWidth(nxagentDisplay, DefaultScreen(nxagentDisplay)); + nxagentDisplayHeightRecBackup = DisplayHeight(nxagentDisplay, DefaultScreen(nxagentDisplay)); + nxagentRenderEnableRecBackup = nxagentRenderEnable; + + nxagentDisplayInfoSaved = True; +} + +void nxagentCleanupBackupDisplayInfo(void) +{ + xfree(nxagentDepthsRecBackup); + nxagentNumDepthsRecBackup = 0; + + nxagentNumDefaultColormapsRecBackup = 0; + + xfree(nxagentVisualsRecBackup); + nxagentNumVisualsRecBackup = 0; + + if (nxagentVisualHasBeenIgnored) + { + xfree(nxagentVisualHasBeenIgnored); + nxagentVisualHasBeenIgnored = NULL; + } + + nxagentDefaultDepthRecBackup = 0; + nxagentDisplayWidthRecBackup = 0; + nxagentDisplayHeightRecBackup = 0; + + if (nxagentDisplayBackup) + { + XCloseDisplay(nxagentDisplayBackup); + + nxagentDisplayBackup = NULL; + } + + if (nxagentBitmapGCBackup) + { + if (nxagentDisplayBackup) + { + XFreeGC(nxagentDisplayBackup, nxagentBitmapGCBackup); + } + else + { + xfree(nxagentBitmapGCBackup); + } + + nxagentBitmapGCBackup = NULL; + } + + nxagentDisplayInfoSaved = False; +} + +void nxagentDisconnectDisplay(void) +{ + switch (reconnectDisplayState) + { + case EVERYTHING_DONE: + if (nxagentBitmapGC && + nxagentBitmapGCBackup && + (nxagentBitmapGC != nxagentBitmapGCBackup)) + { + XFreeGC(nxagentDisplay, nxagentBitmapGC); + } + + nxagentBitmapGC = nxagentBitmapGCBackup; + case GOT_PIXMAP_FORMAT_LIST: + case GOT_DEPTH_LIST: + case ALLOC_DEF_COLORMAP: + if (nxagentDefaultColormaps) + { + int i; + + for (i = 0; i < nxagentNumDefaultColormaps; i++) + { + nxagentDefaultColormaps[i] = None; + } + } + case GOT_VISUAL_INFO: + case OPENED: + /* + * Actually we need the nxagentDisplay + * structure in order to let the agent + * go when no X connection is available. + */ + + if (nxagentDisplay && + nxagentDisplayBackup && + (nxagentDisplay != nxagentDisplayBackup)) + { + XCloseDisplay(nxagentDisplay); + } + case NOTHING: + nxagentDisplay = nxagentDisplayBackup; + break; + default: + FatalError("Display is in unknown state. Can't continue."); + } + + reconnectDisplayState = NOTHING; +} + +static int nxagentCheckForDefaultDepthCompatibility() +{ + int dDepth; + + dDepth = DefaultDepth(nxagentDisplay, DefaultScreen(nxagentDisplay)); + + if (nxagentDefaultDepthRecBackup == dDepth) + { + #ifdef TEST + fprintf(stderr, "nxagentCheckForDefaultDepthCompatibility: New default depth [%d] " + "matches with old default depth.\n", dDepth); + #endif + + return 1; + } + else + { + #ifdef WARNING + fprintf(stderr, "nxagentCheckForDefaultDepthCompatibility: WARNING! New default depth [%d] " + "doesn't match with old default depth [%d].\n", dDepth, nxagentDefaultDepthRecBackup); + #endif + + return 0; + } +} + +static int nxagentCheckForDepthsCompatibility(int flexibility) +{ + int i, j; + int matched; + int compatible; + + if (nxagentNumDepths != nxagentNumDepthsRecBackup) + { + #ifdef WARNING + fprintf(stderr, "nxagentCheckForDepthsCompatibility: WARNING! Number of new available depths [%d] " + "doesn't match with old depths [%d].\n", nxagentNumDepths, + nxagentNumDepthsRecBackup); + #endif + + return 0; + } + + compatible = 1; + + for (i = 0; i < nxagentNumDepths; i++) + { + matched = 0; + + for (j = 0; j < nxagentNumDepthsRecBackup; j++) + { + if (nxagentDepths[i] == nxagentDepthsRecBackup[j]) + { + matched = 1; + + break; + } + } + + if (matched == 0) + { + #ifdef WARNING + fprintf(stderr, "nxagentCheckForDepthsCompatibility: WARNING! Failed to match available depth [%d].\n", + nxagentDepths[i]); + #endif + + compatible = 0; + + break; + } + } + + + if (compatible == 1) + { + #ifdef TEST + fprintf(stderr, "nxagentCheckForDepthsCompatibility: Internal depths match with " + "remote depths.\n"); + #endif + } + else + { + #ifdef WARNING + fprintf(stderr, "nxagentCheckForDepthsCompatibility: WARNING! New available depths don't match with " + "old depths.\n"); + #endif + } + + return compatible; +} + +static int nxagentCheckForPixmapFormatsCompatibility() +{ + int i, j; + int matched; + int compatible; + + compatible = 1; + + if (nxagentNumPixmapFormats != nxagentRemoteNumPixmapFormats) + { + #ifdef DEBUG + fprintf(stderr, "nxagentCheckForPixmapFormatsCompatibility: WARNING! Number of internal pixmap formats [%d] " + "doesn't match with remote formats [%d].\n", nxagentNumPixmapFormats, + nxagentRemoteNumPixmapFormats); + #endif + } + + for (i = 0; i < nxagentNumPixmapFormats; i++) + { + matched = 0; + + for (j = 0; j < nxagentRemoteNumPixmapFormats; j++) + { + if (nxagentPixmapFormats[i].depth == nxagentRemotePixmapFormats[j].depth && + nxagentPixmapFormats[i].bits_per_pixel == nxagentRemotePixmapFormats[j].bits_per_pixel && + nxagentPixmapFormats[i].scanline_pad == nxagentRemotePixmapFormats[j].scanline_pad) + { + matched = 1; + + break; + } + } + + if (matched == 0) + { + #ifdef WARNING + fprintf(stderr, "nxagentCheckForPixmapFormatsCompatibility: WARNING! Failed to match internal " + "pixmap format depth [%d] bpp [%d] pad [%d].\n", nxagentPixmapFormats[i].depth, + nxagentPixmapFormats[i].bits_per_pixel, nxagentPixmapFormats[i].scanline_pad); + #endif + + compatible = 0; + } + } + + #ifdef TEST + + if (compatible == 1) + { + fprintf(stderr, "nxagentCheckForPixmapFormatsCompatibility: Internal pixmap formats match with " + "remote pixmap formats.\n"); + } + + #endif + + return compatible; +} + +static int nxagentInitAndCheckVisuals(int flexibility) +{ + XVisualInfo viTemplate; + XVisualInfo *viList; + XVisualInfo *newVisuals; + + long viMask; + int i, n; + int matched; + int compatible; + int viNumList; + + compatible = 1; + + viMask = VisualScreenMask; + viTemplate.screen = DefaultScreen(nxagentDisplay); + viTemplate.depth = DefaultDepth(nxagentDisplay, DefaultScreen(nxagentDisplay)); + viList = XGetVisualInfo(nxagentDisplay, viMask, &viTemplate, &viNumList); + + newVisuals = malloc(sizeof(XVisualInfo) * nxagentNumVisuals); + + for (i = 0; i < nxagentNumVisuals; i++) + { + matched = 0; + + for (n = 0; n < viNumList; n++) + { + if (nxagentCompareVisuals(nxagentVisuals[i], viList[n]) == 1) + { +/* +FIXME: Should the visual be ignored in this case? + We can flag the visuals with inverted masks, + and use this information to switch the masks + when contacting the remote X server. +*/ + if (nxagentVisuals[i].red_mask == viList[n].blue_mask && + nxagentVisuals[i].blue_mask == viList[n].red_mask) + { + #ifdef WARNING + fprintf(stderr, "nxagentInitAndCheckVisuals: WARNING! Red and blue mask inverted. " + "Forcing matching.\n"); + #endif + } + + matched = 1; + + nxagentVisualHasBeenIgnored[i] = FALSE; + + memcpy(newVisuals + i, viList + n, sizeof(XVisualInfo)); + + break; + } + } + + if (matched == 0) + { + if (nxagentVisuals[i].class == DirectColor) + { + #ifdef WARNING + fprintf(stderr, "nxagentInitAndCheckVisuals: WARNING! Ignoring not matched DirectColor visual.\n"); + #endif + + nxagentVisualHasBeenIgnored[i] = TRUE; + + memcpy(newVisuals + i, nxagentVisuals + i, sizeof(XVisualInfo)); + } + else + { + #ifdef DEBUG + fprintf(stderr, "nxagentInitAndCheckVisuals: WARNING! Failed to match this visual:\n"); + fprintf(stderr, "\tdepth = %d\n", nxagentVisuals[i].depth); + fprintf(stderr, "\tclass = %d\n", nxagentVisuals[i].class); + fprintf(stderr, "\tmask = (%ld,%ld,%ld)\n", + nxagentVisuals[i].red_mask, + nxagentVisuals[i].green_mask, + nxagentVisuals[i].blue_mask); + fprintf(stderr, "\tcolormap size = %d\n", nxagentVisuals[i].colormap_size); + fprintf(stderr, "\tbits_per_rgb = %d\n", nxagentVisuals[i].bits_per_rgb); + #endif + + compatible = 0; + + break; + } + } + } + + XFree(viList); + + if (compatible == 1) + { + #ifdef TEST + fprintf(stderr, "nxagentInitAndCheckVisuals: New visuals match with old visuals.\n"); + #endif + + nxagentVisuals = newVisuals; + } + else + { + #ifdef WARNING + fprintf(stderr, "nxagentInitAndCheckVisuals: New visuals don't match with old visuals.\n"); + #endif + + free(newVisuals); + } + + return compatible; +} + +static int nxagentCheckForColormapsCompatibility(int flexibility) +{ + if (nxagentNumDefaultColormaps == nxagentNumDefaultColormapsRecBackup) + { + #ifdef TEST + fprintf(stderr, "nxagentCheckForColormapsCompatibility: Number of new colormaps [%d] " + "matches with old colormaps.\n", nxagentNumDefaultColormaps); + #endif + + return 1; + } + else + { + #ifdef WARNING + fprintf(stderr, "nxagentCheckForColormapsCompatibility: WARNING! Number of new colormaps [%d] " + "doesn't match with old colormaps [%d].\n", nxagentNumDefaultColormaps, + nxagentNumDefaultColormapsRecBackup); + #endif + + return 0; + } +} + +Bool nxagentReconnectDisplay(void *p0) +{ + int i; + int flexibility = *(int*)p0; + int packMethod, packQuality; + + #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_DISPLAY_DEBUG) + fprintf(stderr, "nxagentReconnectDisplay\n"); + #endif + + if (reconnectDisplayState) + { + fprintf(stderr, "nxagentReconnectDisplay: Trying to reconnect a session " + "uncleanly disconnected\n"); + + return False; + } + + /* + * Reset the values to their defaults. + */ + + packMethod = nxagentPackMethod; + packQuality = nxagentPackQuality; + + nxagentPackMethod = -1; + nxagentPackQuality = -1; + nxagentSplitThreshold = -1; + + nxagentRemoteMajor = -1; + + nxagentInstallSignalHandlers(); + + nxagentInstallDisplayHandlers(); + + nxagentDisplay = nxagentInternalOpenDisplay(nxagentDisplayName); + + nxagentPostInstallSignalHandlers(); + + nxagentPostInstallDisplayHandlers(); + + if (nxagentDisplay == NULL) + { + nxagentSetReconnectError(FAILED_RESUME_DISPLAY_ALERT, + "Couldn't open the display."); + + return FALSE; + } + + nxagentAddXConnection(); + + /* + * Display is now open. + */ + + reconnectDisplayState = OPENED; + + #ifdef NXAGENT_TIMESTAMP + + fprintf(stderr, "Display: Open of the display finished with time [%d] ms.\n", + GetTimeInMillis() - startTime); + + #endif + + if (nxagentCheckForDefaultDepthCompatibility() == 0) + { + nxagentSetReconnectError(FAILED_RESUME_DISPLAY_ALERT, + "Default display depth doesn't match."); + + return FALSE; + } + + nxagentUseNXTrans = nxagentPostProcessArgs(nxagentDisplayName, nxagentDisplay, + DefaultScreenOfDisplay(nxagentDisplay)); + + /* + * After processing the arguments all the + * timeout values have been set. Now we + * have to change the screen-saver timeout. + */ + + nxagentSetScreenSaverTime(); + + /* + * Init and compare the visuals. + */ + + if (nxagentInitAndCheckVisuals(flexibility) == FALSE) + { + nxagentSetReconnectError(FAILED_RESUME_VISUALS_ALERT, + "Couldn't restore the required visuals."); + + return FALSE; + } + + reconnectDisplayState = GOT_VISUAL_INFO; + + nxagentSetDefaultVisual(); + + nxagentInitAlphaVisual(); + + /* + * Re-allocate the colormaps. + */ + + nxagentNumDefaultColormaps = nxagentNumVisuals; + + nxagentDefaultColormaps = (Colormap *) xrealloc(nxagentDefaultColormaps, + nxagentNumDefaultColormaps * sizeof(Colormap)); + + if (nxagentDefaultColormaps == NULL) + { + FatalError("Can't allocate memory for the default colormaps\n"); + } + + reconnectDisplayState = ALLOC_DEF_COLORMAP; + + for (i = 0; i < nxagentNumDefaultColormaps; i++) + { + if (nxagentVisualHasBeenIgnored[i]) + { + nxagentDefaultColormaps[i] = (XID)0; + } + else + { + nxagentDefaultColormaps[i] = XCreateColormap(nxagentDisplay, + DefaultRootWindow(nxagentDisplay), + nxagentVisuals[i].visual, + AllocNone); + } + } + + nxagentCheckForColormapsCompatibility(flexibility); + + /* + * Check the display depth. + */ + + nxagentInitDepths(); + + reconnectDisplayState = GOT_DEPTH_LIST; + + if (nxagentCheckForDepthsCompatibility(flexibility) == 0) + { + nxagentSetReconnectError(FAILED_RESUME_DEPTHS_ALERT, + "Couldn't restore all the required depths."); + + return False; + } + + /* + * nxagentPixmapFormats and nxagentRemotePixmapFormats + * will be reallocated in nxagentInitPixmapFormats(). + */ + + if (nxagentPixmapFormats != NULL) + { + XFree(nxagentPixmapFormats); + + nxagentPixmapFormats = NULL; + } + + if (nxagentRemotePixmapFormats != NULL) + { + XFree(nxagentRemotePixmapFormats); + + nxagentRemotePixmapFormats = NULL; + } + + /* + * Check if all the required pixmap + * formats are supported. + */ + + nxagentInitPixmapFormats(); + + reconnectDisplayState = GOT_PIXMAP_FORMAT_LIST; + + /* + * Create a pixmap for each depth matching the + * local supported formats with format available + * on the remote display. + */ + + nxagentSetDefaultDrawables(); + + #ifdef RENDER + + if (nxagentRenderEnable) + { + nxagentRenderExtensionInit(); + } + + if (nxagentRenderEnableRecBackup != nxagentRenderEnable) + { + nxagentRenderEnable = nxagentRenderEnableRecBackup; + + nxagentSetReconnectError(FAILED_RESUME_RENDER_ALERT, + "Render extension not available or incompatible version."); + + return False; + } + + #endif + + nxagentBlackPixel = BlackPixel(nxagentDisplay, DefaultScreen(nxagentDisplay)); + nxagentWhitePixel = WhitePixel(nxagentDisplay, DefaultScreen(nxagentDisplay)); + + /* + * Initialize the agent's event mask that will be requested + * for the root or all the top level windows. If the nested + * window is a child of an existing window we will need to + * receive StructureNotify events. If we are going to manage + * the changes in root window's visibility we'll also need + * VisibilityChange events. + */ + + nxagentInitDefaultEventMask(); + + nxagentBitmapGC = XCreateGC(nxagentDisplay, nxagentDefaultDrawables[1], 0L, NULL); + + #ifdef TEST + fprintf(stderr, "nxagentReconnectDisplay: Going to create agent's confine window.\n"); + #endif + + nxagentConfineWindow = XCreateWindow(nxagentDisplay, + DefaultRootWindow(nxagentDisplay), + 0, 0, 1, 1, 0, 0, + InputOnly, + CopyFromParent, + 0L, NULL); + + #ifdef TEST + fprintf(stderr, "nxagentReconnectDisplay: Created agent's confine window with id [%ld].\n", + nxagentConfineWindow); + #endif + + nxagentLogoDepth = DefaultDepth(nxagentDisplay, DefaultScreen(nxagentDisplay)); + + pV = nxagentVisuals[nxagentDefaultVisualIndex]; + + r = pV.red_mask; + g = pV.green_mask; + b = pV.blue_mask; + + if (!pV.red_mask || !pV.green_mask || !pV.blue_mask) + { + nxagentLogoBlack = 0x000000; + nxagentLogoRed = 0xff0000; + nxagentLogoWhite = 0xffffff; + } + else + { + for (or=0, off=0x800000; (r&(off>>or)) == 0; or++); + for (og=0, off=0x800000; (g&(off>>og)) == 0; og++); + for (ob=0, off=0x800000; (b&(off>>ob)) == 0; ob++); + + nxagentLogoRed = nxagentLogoColor(0xff0000); + nxagentLogoBlack = nxagentLogoColor(0x000000); + nxagentLogoWhite = 0xffffff; + } + + useXpmIcon = nxagentMakeIcon(nxagentDisplay, &nxagentIconPixmap, &nxagentIconShape); + + /* + * All went fine. We can continue + * handling our clients. + */ + + reconnectDisplayState = EVERYTHING_DONE; + + return True; +} + +void nxagentAddXConnection() +{ + int fd = XConnectionNumber(nxagentDisplay); + + nxagentXConnectionNumber = fd; + + #ifdef TEST + fprintf(stderr, "nxagentAddXConnection: Adding the X connection [%d] " + "to the device set.\n", nxagentXConnectionNumber); + #endif + + AddEnabledDevice(nxagentXConnectionNumber); +} + +void nxagentRemoveXConnection() +{ + #ifdef TEST + fprintf(stderr, "nxagentRemoveXConnection: Removing the X connection [%d] " + "from the device set.\n", nxagentXConnectionNumber); + #endif + + RemoveEnabledDevice(nxagentXConnectionNumber); +} + +/* + * Force an I/O error and wait until the NX trans- + * port is gone. It must be called before suspend- + * ing or terminating a session to ensure that the + * NX transport is terminated first. + */ + +void nxagentWaitDisplay() +{ + /* + * Disable the smart scheduler's interrupts. + */ + + #ifdef SMART_SCHEDULE + + #ifdef DEBUG + fprintf(stderr, "nxagentWaitDisplay: Stopping the smart schedule timer.\n"); + #endif + + nxagentStopTimer(); + + #endif + + if (nxagentDisplay != NULL) + { + #ifdef TEST + fprintf(stderr, "nxagentWaitDisplay: Going to shutdown the X connection [%d].\n", + nxagentXConnectionNumber); + #endif + + NXForceDisplayError(nxagentDisplay); + + XSync(nxagentDisplay, 0); + } + + #ifdef TEST + fprintf(stderr, "nxagentWaitDisplay: Going to wait for the NX transport.\n"); + #endif + + NXTransDestroy(NX_FD_ANY); + + #ifdef TEST + fprintf(stderr, "nxagentWaitDisplay: The NX transport is not running.\n"); + #endif + + /* + * Be sure the signal handlers are + * in a known state. + */ + + nxagentResetSignalHandlers(); +} + +/* + * This has not to do with the remote display but + * with the X server that the agent is impersonating. + * We have it here to be consistent with the other + * cleanup procedures which have mainly to do with + * the Xlib display connection. + */ + +void nxagentAbortDisplay() +{ + /* + * Be sure the X server socket in .X11-unix is + * deleted otherwise other users may to become + * unable to run a session on the same display. + */ + + #ifdef TEST + fprintf(stderr, "nxagentAbortDisplay: Cleaning up the X server sockets.\n"); + #endif + + CloseWellKnownConnections(); +} diff --git a/programs/Xserver/hw/nxagent/Events.c b/programs/Xserver/hw/nxagent/Events.c index b9da934..ce84c1b 100644 --- a/programs/Xserver/hw/nxagent/Events.c +++ b/programs/Xserver/hw/nxagent/Events.c @@ -591,8 +591,8 @@ void nxagentSwitchResizeMode(ScreenPtr pScreen) nxagentLaunchDialog(DIALOG_ENABLE_DESKTOP_RESIZE_MODE); - nxagentRRSetScreenConfig(pScreen, nxagentOption(Width), - nxagentOption(Height)); + nxagentChangeScreenConfig(0, nxagentOption(Width), nxagentOption(Height), + 0, 0); if (nxagentOption(ClientOs) == ClientOsWinnt) { @@ -3461,8 +3461,8 @@ int nxagentHandleConfigureNotify(XEvent* X) nxagentOption(Width), nxagentOption(Height)); #endif - nxagentRRSetScreenConfig(screenInfo.screens[DefaultScreen(nxagentDisplay)], - nxagentOption(Width), nxagentOption(Height)); + nxagentChangeScreenConfig(0, nxagentOption(Width), + nxagentOption(Height), 0, 0); } } diff --git a/programs/Xserver/hw/nxagent/Extensions.c b/programs/Xserver/hw/nxagent/Extensions.c index aced24f..6dce644 100644 --- a/programs/Xserver/hw/nxagent/Extensions.c +++ b/programs/Xserver/hw/nxagent/Extensions.c @@ -22,11 +22,19 @@ #include "Agent.h" #include "Display.h" #include "Screen.h" +#include "Options.h" #include "Extensions.h" +#include "Windows.h" void GlxExtensionInit(void); void GlxWrapInitVisuals(void *procPtr); +static int nxagentRandRScreenSetSize(ScreenPtr pScreen, CARD16 width, + CARD16 height, CARD32 mmWidth, + CARD32 mmHeight); + +static int nxagentRandRInitSizes(ScreenPtr pScreen); + #ifdef __DARWIN__ void DarwinHandleGUI(int argc, char *argv[]) @@ -75,6 +83,8 @@ void nxagentInitRandRExtension(ScreenPtr pScreen) fprintf(stderr, "Warning: Failed to initialize the RandR extension.\n"); } + nxagentRandRInitSizes(pScreen); + /* * RRScreenInit sets these pointers to NULL, * so requiring the server to set up its own @@ -84,12 +94,31 @@ void nxagentInitRandRExtension(ScreenPtr pScreen) pRandRScrPriv = rrGetScrPriv(pScreen); pRandRScrPriv -> rrGetInfo = nxagentRandRGetInfo; + + #if RANDR_12_INTERFACE + pRandRScrPriv -> rrScreenSetSize = nxagentRandRScreenSetSize; + #endif + + #if RANDR_10_INTERFACE pRandRScrPriv -> rrSetConfig = nxagentRandRSetConfig; + #endif } int nxagentRandRGetInfo(ScreenPtr pScreen, Rotation *pRotations) { + /* + * Rotation is not supported. + */ + + *pRotations = RR_Rotate_0; + + return 1; +} + +static int nxagentRandRInitSizes(ScreenPtr pScreen) +{ RRScreenSizePtr pSize; + rrScrPrivPtr pRandRScrPriv = rrGetScrPriv(pScreen); int width; int height; @@ -97,8 +126,16 @@ int nxagentRandRGetInfo(ScreenPtr pScreen, Rotation *pRotations) int maxWidth; int maxHeight; - int w[] = {0, 160, 320, 640, 800, 1024, 0, 0}; - int h[] = {0, 120, 240, 480, 600, 768, 0, 0}; +/* + int w[] = {0, 160, 320, 640, 800, 1024, 1152, 1280, 1280, 1280, 1280, 1280, + 1280, 1360, 1440, 1600, 1600, 1680, 1920, 1920, 0, 0}; + int h[] = {0, 120, 240, 480, 600, 768, 864, 600, 720, 800, 854, 960, + 1024, 768, 900, 900, 1200, 1050, 1080, 1200, 0, 0}; +*/ + int w[] = {0, 320, 640, 640, 800, 800, 1024, 1024, 1152, 1280, 1280, 1280, 1360, + 1440, 1600, 1600, 1680, 1920, 1920, 0, 0}; + int h[] = {0, 240, 360, 480, 480, 600, 600, 768, 864, 720, 800, 1024, 768, + 900, 900, 1200, 1050, 1080, 1200, 0, 0}; int i; int nSizes; @@ -107,12 +144,6 @@ int nxagentRandRGetInfo(ScreenPtr pScreen, Rotation *pRotations) int mmHeight; /* - * Rotation is not supported. - */ - - *pRotations = RR_Rotate_0; - - /* * Register all the supported sizes. The third * parameter is the refresh rate. */ @@ -185,13 +216,106 @@ int nxagentRandRGetInfo(ScreenPtr pScreen, Rotation *pRotations) return 1; } +#if RANDR_10_INTERFACE + int nxagentRandRSetConfig(ScreenPtr pScreen, Rotation rotation, int rate, RRScreenSizePtr pSize) { + int r; + rrScrPrivPtr pRandRScrPriv; + + UpdateCurrentTime(); + /* * Whatever size is OK for us. */ - return nxagentResizeScreen(pScreen, pSize -> width, pSize -> height, + r = nxagentResizeScreen(pScreen, pSize -> width, pSize -> height, pSize -> mmWidth, pSize -> mmHeight); + + nxagentMoveViewport(pScreen, 0, 0); + + return r; } + +#endif + +#if RANDR_12_INTERFACE + +void nxagentRandRSetWindowsSize(int width, int height) +{ + if (width == 0) + { + if (nxagentOption(Fullscreen) == 1) + { + width = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)); + } + else + { + width = nxagentOption(Width); + } + } + + if (height == 0) + { + if (nxagentOption(Fullscreen) == 1) + { + height = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)); + } + else + { + height = nxagentOption(Height); + } + } + + XResizeWindow(nxagentDisplay, nxagentDefaultWindows[0], width, height); + + if (nxagentOption(Rootless) == 0) + { + XMoveResizeWindow(nxagentDisplay, nxagentInputWindows[0], 0, 0, width, + height); + } +} + +int nxagentRandRScreenSetSize(ScreenPtr pScreen, CARD16 width, CARD16 height, + CARD32 mmWidth, CARD32 mmHeight) +{ + int result; + rrScrPrivPtr pRandRScrPriv; + + UpdateCurrentTime(); + + if (nxagentOption(DesktopResize) == 1 && + (nxagentOption(Fullscreen) == 1 || + width > WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) || + height > HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)))) + { + if (nxagentOption(ClientOs) != ClientOsWinnt + /*&& nxagentOption(ClientOs) != ClientNXPlayer*/) + { + nxagentChangeOption(DesktopResize, 0); + } + } + + if (nxagentOption(DesktopResize) == 1 && nxagentOption(Fullscreen) == 0 && + nxagentOption(AllScreens) == 0) + { + nxagentChangeOption(Width, width); + nxagentChangeOption(Height, height); + } + + result = nxagentResizeScreen(pScreen, width, height, mmWidth, mmHeight); + + if (result == 1 && nxagentOption(DesktopResize) == 1 && + nxagentOption(Fullscreen) == 0 && nxagentOption(AllScreens) == 0) + { + nxagentRandRSetWindowsSize(width, height); + nxagentSetWMNormalHints(pScreen -> myNum); + } + + nxagentMoveViewport(pScreen, 0, 0); + + return result; +} + +#endif diff --git a/programs/Xserver/hw/nxagent/Imakefile b/programs/Xserver/hw/nxagent/Imakefile index 254267e..8847d8e 100644 --- a/programs/Xserver/hw/nxagent/Imakefile +++ b/programs/Xserver/hw/nxagent/Imakefile @@ -7,8 +7,7 @@ SRCS1 = os2Stub.c OBJS1 = os2Stub.o #endif -SRCS = NXrandr.c \ - NXwindow.c \ +SRCS = NXwindow.c \ NXevents.c \ NXproperty.c \ NXdixfonts.c \ @@ -70,8 +69,7 @@ SRCS = NXrandr.c \ miinitext.c \ $(SRCS1) -OBJS = NXrandr.o \ - NXwindow.o \ +OBJS = NXwindow.o \ NXevents.o \ NXproperty.o \ NXdixfonts.o \ @@ -206,6 +204,8 @@ DEFINES = -g $(OS_DEFINES) $(EXT_DEFINES) $(UPG_DEFINES) \ -DNXAGENT_SPLASH \ -DNXAGENT_ARTSD \ -UNX_DEBUG_INPUT \ + -DRANDR_10_INTERFACE \ + -DRANDR_12_INTERFACE \ -UPANORAMIX \ -UDEBUG_TREE diff --git a/programs/Xserver/hw/nxagent/Imakefile.orig b/programs/Xserver/hw/nxagent/Imakefile.orig new file mode 100644 index 0000000..9657958 --- /dev/null +++ b/programs/Xserver/hw/nxagent/Imakefile.orig @@ -0,0 +1,222 @@ +# XCOMM $Xorg: Imakefile,v 1.3 2000/08/17 19:53:28 cpqbld Exp $ + +#include <Server.tmpl> + +#ifdef OS2Architecture +SRCS1 = os2Stub.c +OBJS1 = os2Stub.o +#endif + +SRCS = NXwindow.c \ + NXevents.c \ + NXproperty.c \ + NXdixfonts.c \ + NXglyphcurs.c \ + NXdispatch.c \ + NXrender.c \ + NXglyph.c \ + NXpicture.c \ + NXextension.c \ + NXshm.c \ + NXglxext.c \ + NXxvdisp.c \ + NXmiglyph.c \ + NXmiexpose.c \ + NXresource.c \ + NXmiwindow.c \ + NXxrandr.c \ + NXdamage.c \ + NXmitrap.c \ + Args.c \ + Binder.c \ + Colormap.c \ + Cursor.c \ + Dialog.c \ + Display.c \ + Events.c \ + Font.c \ + GC.c \ + GCOps.c \ + Millis.c \ + Handlers.c \ + Init.c \ + Keyboard.c \ + Keystroke.c \ + Pointer.c \ + Screen.c \ + TestExt.c \ + Visual.c \ + Drawable.c \ + Window.c \ + Pixmap.c \ + Render.c \ + Client.c \ + Rootless.c \ + Extensions.c \ + Options.c \ + Clipboard.c \ + Splash.c \ + Split.c \ + Holder.c \ + Reconnect.c \ + Error.c \ + Atoms.c \ + Trap.c \ + Image.c \ + Composite.c \ + Pixels.c \ + stubs.c \ + miinitext.c \ + $(SRCS1) + +OBJS = NXwindow.o \ + NXevents.o \ + NXproperty.o \ + NXdixfonts.o \ + NXglyphcurs.o \ + NXdispatch.o \ + NXrender.o \ + NXglyph.o \ + NXpicture.o \ + NXextension.o \ + NXshm.o \ + NXglxext.o \ + NXxvdisp.o \ + NXmiglyph.o \ + NXmiexpose.o \ + NXresource.o \ + NXmiwindow.o \ + NXxrandr.o \ + NXdamage.o \ + NXmitrap.o \ + Args.o \ + Binder.o \ + Colormap.o \ + Cursor.o \ + Dialog.o \ + Display.o \ + Events.o \ + Font.o \ + GC.o \ + GCOps.o \ + Millis.o \ + Handlers.o \ + Init.o \ + Keyboard.o \ + Keystroke.o \ + Pointer.o \ + Screen.o \ + TestExt.o \ + Visual.o \ + Drawable.o \ + Window.o \ + Pixmap.o \ + Render.o \ + Client.o \ + Rootless.o \ + Extensions.o \ + Options.o \ + Clipboard.o \ + Splash.o \ + Split.o \ + Holder.o \ + Reconnect.o \ + Error.o \ + Atoms.o \ + Trap.o \ + Image.o \ + Composite.o \ + Pixels.o \ + stubs.o \ + miinitext.o \ + $(OBJS1) + +VFBINCLUDES = -I../../fb -I../../mfb -I../../render +NXFONTINCLUDES = -I../../../../lib/font/include +LIBXRANDRINCLUDES= -I../../../../lib/Xrandr + +INCLUDES = -I. -I../../../../../nxcomp -I../../../../../nxcompext -I../../../../../nxcompshad \ + -I../../../../extras/Mesa/include \ + -I$(XBUILDINCDIR) -I$(FONTINCSRC) \ + -I../../mi -I../../include -I../../os \ + -I../../miext/damage -I../../miext/cw \ + -I../../GL/glx -I../../GL/include -I../../../../lib/GL/include -I../../Xext \ + -I$(EXTINCSRC) -I$(XINCLUDESRC) \ + $(VFBINCLUDES) $(NXFONTINCLUDES) $(LIBXRANDRINCLUDES) +#ifdef SunArchitecture +INCLUDES = -I. -I../../../../../nxcomp -I../../../../../nxcompext -I../../../../../nxcompshad \ + -I../../../../extras/Mesa/include \ + -I$(XBUILDINCDIR) -I$(FONTINCSRC) \ + -I/usr/sfw/include \ + -I../../mi -I../../include -I../../os \ + -I../../GL/glx -I../../GL/include -I../../../../lib/GL/include -I../../Xext \ + -I../../miext/damage -I../../miext/cw \ + -I$(EXTINCSRC) -I$(XINCLUDESRC) \ + $(VFBINCLUDES) $(NXFONTINCLUDES) $(LIBXRANDRINCLUDES) +#else +#ifdef cygwinArchitecture +INCLUDES = -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \ + -I../../mi -I../../include -I../../os \ + -I../../GL/glx -I../../GL/include -I../../../../lib/GL/include -I../../Xext \ + -I../../miext/damage -I../../miext/cw \ + -I../../../../../nxcomp -I../../../../../nxcompext -I../../../../../nxcompshad \ + -I../../../../extras/Mesa/include \ + -I$(EXTINCSRC) -I$(XINCLUDESRC) \ + $(VFBINCLUDES) $(NXFONTINCLUDES) $(LIBXRANDRINCLUDES) +#endif +#endif + +### NXAGENT Defines: +# +# NXAGENT_FONTCACHE_SIZE Number of cache slots +# NXAGENT_SHAPE Old shape code +# NXAGENT_GLYPHCACHE +# NXAGENT_GLYPHCACHE_SIZE Slots for glyph cache +# NXAGENT_SHAPE2 New shape code +# NXAGENT_FIXKEYS Force the release of pressed key when loosing focus +# NXAGENT_EXPOSURES Manage expose events +# NXAGENT_CLIPBOARD Enables clipboard cut and paste function between X servers. +# NXAGENT_FONTEXCLUDE Exclude some specific font names (only "-ult1mo" at this moment). +# NXAGENT FULLSCREEN Fullscreen mode +# + +#if NXUpgradeAgentServer +UPG_DEFINES=-DNXAGENT_UPGRADE +#else +UPG_DEFINES= +#endif + +DEFINES = -g $(OS_DEFINES) $(EXT_DEFINES) $(UPG_DEFINES) \ + -UXF86VIDMODE -UXFreeXDGA -UXF86MISC -UXF86DRI -UXFree86LOADER \ + -DNXAGENT_SERVER \ + -DNXAGENT_CONSTRAINCURSOR \ + -DNXAGENT_FONTCACHE_SIZE=50 \ + -DNXAGENT_GLYPHCACHE -DNXAGENT_GLYPHCACHE_SIZE=50 \ + -DNXAGENT_SHAPE2 \ + -DNXAGENT_FIXKEYS \ + -DNXAGENT_CLIPBOARD \ + -DNXAGENT_EXPOSURES \ + -DNXAGENT_FONTEXCLUDE \ + -DNXAGENT_PACKEDIMAGES \ + -DNXAGENT_VISIBILITY \ + -DNXAGENT_WAKEUP=1000 \ + -DNXAGENT_ONSTART \ + -DNXAGENT_SPLASH \ + -DNXAGENT_ARTSD \ + -UNX_DEBUG_INPUT \ + -DRANDR_10_INTERFACE \ + -DRANDR_12_INTERFACE \ + -UPANORAMIX \ + -UDEBUG_TREE + +all:: $(OBJS) + +LinkSourceFile(stubs.c,$(SERVERSRC)/Xi) +SpecialCObjectRule(Init,$(ICONFIGFILES),$(_NOOP_)) +LinkSourceFile(miinitext.c,$(SERVERSRC)/mi) +SpecialCObjectRule(miinitext,$(ICONFIGFILES), $(_NOOP_)) + +NormalLibraryObjectRule() +NormalLibraryTarget(nxagent,$(OBJS)) + +DependTarget() diff --git a/programs/Xserver/hw/nxagent/Init.c b/programs/Xserver/hw/nxagent/Init.c index 89a85db..ee4bd3a 100644 --- a/programs/Xserver/hw/nxagent/Init.c +++ b/programs/Xserver/hw/nxagent/Init.c @@ -128,6 +128,10 @@ void OsVendorEndRedirectErrorFFunction(); * new X server tree. */ + +static void nxagentGrabServerCallback(CallbackListPtr *callbacks, pointer data, + pointer args); + #ifdef NXAGENT_UPGRADE void ddxInitGlobals(void) @@ -209,6 +213,11 @@ void InitOutput(ScreenInfo *screenInfo, int argc, char *argv[]) NXUnsetLibraryPath(1); + if (serverGeneration == 1) + { + AddCallback(&ServerGrabCallback, nxagentGrabServerCallback, NULL); + } + if (nxagentUserDefinedFontPath == 0) { #ifdef TEST @@ -479,6 +488,17 @@ void OsVendorEndRedirectErrorFFunction() int SelectWaitTime = 10000; /* usec */ #endif +ServerGrabInfoRec nxagentGrabServerInfo; + +static void nxagentGrabServerCallback(CallbackListPtr *callbacks, pointer data, + pointer args) +{ + ServerGrabInfoRec *grab = (ServerGrabInfoRec*)args; + + nxagentGrabServerInfo.client = grab->client; + nxagentGrabServerInfo.grabstate = grab->grabstate; +} + #ifdef DPMSExtension void DPMSSet(int level) diff --git a/programs/Xserver/hw/nxagent/Init.h b/programs/Xserver/hw/nxagent/Init.h index cf154e8..2dc0f5c 100644 --- a/programs/Xserver/hw/nxagent/Init.h +++ b/programs/Xserver/hw/nxagent/Init.h @@ -37,4 +37,6 @@ extern int nxagentDoFullGeneration; extern int nxagentBackingStore; extern int nxagentSaveUnder; +extern ServerGrabInfoRec nxagentGrabServerInfo; + #endif /* __Init_H__ */ diff --git a/programs/Xserver/hw/nxagent/NXrandr.c b/programs/Xserver/hw/nxagent/NXrandr.c deleted file mode 100644 index d593fa6..0000000 --- a/programs/Xserver/hw/nxagent/NXrandr.c +++ /dev/null @@ -1,1229 +0,0 @@ -#ifdef NXAGENT_UPGRADE - -#include "X/NXrandr.c" - -#else - -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */ -/* */ -/* NXAGENT, NX protocol compression and NX extensions to this software */ -/* are copyright of NoMachine. Redistribution and use of the present */ -/* software is allowed according to terms specified in the file LICENSE */ -/* which comes in the source distribution. */ -/* */ -/* Check http://www.nomachine.com/licensing.html for applicability. */ -/* */ -/* NX and NoMachine are trademarks of Medialogic S.p.A. */ -/* */ -/* All rights reserved. */ -/* */ -/**************************************************************************/ - -/* - * $XFree86: xc/programs/Xserver/randr/randr.c,v 1.19 2003/02/08 03:52:30 dawes Exp $ - * - * Copyright � 2000, Compaq Computer Corporation, - * Copyright � 2002, Hewlett Packard, 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 Compaq or HP not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. HP makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL HP - * 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. - * - * Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc. - */ - - -#define NEED_REPLIES -#define NEED_EVENTS -#include "X.h" -#include "Xproto.h" -#include "misc.h" -#include "os.h" -#include "dixstruct.h" -#include "resource.h" -#include "scrnintstr.h" -#include "windowstr.h" -#include "pixmapstr.h" -#include "extnsionst.h" -#include "servermd.h" -#include "randr.h" -#include "randrproto.h" -#include "../../randr/randrstr.h" -#include "render.h" /* we share subpixel order information */ -#include "picturestr.h" -#include "Xfuncproto.h" -#ifdef EXTMODULE -#include "xf86_ansic.h" -#endif - -#define RR_VALIDATE -int RRGeneration; -int RRNScreens; - -static int ProcRRQueryVersion (ClientPtr pClient); -static int ProcRRDispatch (ClientPtr pClient); -static int SProcRRDispatch (ClientPtr pClient); -static int SProcRRQueryVersion (ClientPtr pClient); - -#define wrap(priv,real,mem,func) {\ - priv->mem = real->mem; \ - real->mem = func; \ -} - -#define unwrap(priv,real,mem) {\ - real->mem = priv->mem; \ -} - -static CARD8 RRReqCode; -static int RRErrBase; -static int RREventBase; -static RESTYPE ClientType, EventType; /* resource types for event masks */ -static int RRClientPrivateIndex; - -typedef struct _RRTimes { - TimeStamp setTime; - TimeStamp configTime; -} RRTimesRec, *RRTimesPtr; - -typedef struct _RRClient { - int major_version; - int minor_version; -/* RRTimesRec times[0]; */ -} RRClientRec, *RRClientPtr; - -/* - * each window has a list of clients requesting - * RRNotify events. Each client has a resource - * for each window it selects RRNotify input for, - * this resource is used to delete the RRNotifyRec - * entry from the per-window queue. - */ - -typedef struct _RREvent *RREventPtr; - -typedef struct _RREvent { - RREventPtr next; - ClientPtr client; - WindowPtr window; - XID clientResource; - int mask; -} RREventRec; - -int rrPrivIndex = -1; - -#define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr) -#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient) - -static Bool -RRClientKnowsRates (ClientPtr pClient) -{ - rrClientPriv(pClient); - - return (pRRClient->major_version > 1 || - (pRRClient->major_version == 1 && pRRClient->minor_version >= 1)); -} - -static void -RRClientCallback (CallbackListPtr *list, - pointer closure, - pointer data) -{ - NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; - ClientPtr pClient = clientinfo->client; - rrClientPriv(pClient); - RRTimesPtr pTimes = (RRTimesPtr) (pRRClient + 1); - int i; - - pRRClient->major_version = 0; - pRRClient->minor_version = 0; - for (i = 0; i < screenInfo.numScreens; i++) - { - ScreenPtr pScreen = screenInfo.screens[i]; - rrScrPriv(pScreen); - - if (pScrPriv) - { - pTimes[i].setTime = pScrPriv->lastSetTime; - pTimes[i].configTime = pScrPriv->lastConfigTime; - } - } -} - -static void -RRResetProc (ExtensionEntry *extEntry) -{ -} - -static Bool -RRCloseScreen (int i, ScreenPtr pScreen) -{ - rrScrPriv(pScreen); - - unwrap (pScrPriv, pScreen, CloseScreen); - if (pScrPriv->pSizes) - xfree (pScrPriv->pSizes); - xfree (pScrPriv); - RRNScreens -= 1; /* ok, one fewer screen with RandR running */ - return (*pScreen->CloseScreen) (i, pScreen); -} - -static void -SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from, - xRRScreenChangeNotifyEvent *to) -{ - to->type = from->type; - to->rotation = from->rotation; - cpswaps(from->sequenceNumber, to->sequenceNumber); - cpswapl(from->timestamp, to->timestamp); - cpswapl(from->configTimestamp, to->configTimestamp); - cpswapl(from->root, to->root); - cpswapl(from->window, to->window); - cpswaps(from->sizeID, to->sizeID); - 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); -} - -Bool RRScreenInit(ScreenPtr pScreen) -{ - rrScrPrivPtr pScrPriv; - - if (RRGeneration != serverGeneration) - { - if ((rrPrivIndex = AllocateScreenPrivateIndex()) < 0) - return FALSE; - RRGeneration = serverGeneration; - } - - pScrPriv = (rrScrPrivPtr) xalloc (sizeof (rrScrPrivRec)); - if (!pScrPriv) - return FALSE; - - SetRRScreen(pScreen, pScrPriv); - - /* - * Calling function best set these function vectors - */ - pScrPriv->rrSetConfig = 0; - pScrPriv->rrGetInfo = 0; - /* - * This value doesn't really matter -- any client must call - * GetScreenInfo before reading it which will automatically update - * the time - */ - pScrPriv->lastSetTime = currentTime; - pScrPriv->lastConfigTime = currentTime; - - wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen); - - pScrPriv->rotations = RR_Rotate_0; - - pScrPriv->nSizes = 0; - pScrPriv->nSizesInUse = 0; - pScrPriv->pSizes = 0; - - pScrPriv->rotation = RR_Rotate_0; - pScrPriv->size = -1; - - RRNScreens += 1; /* keep count of screens that implement randr */ - return TRUE; -} - -/*ARGSUSED*/ -static int -RRFreeClient (pointer data, XID id) -{ - RREventPtr pRREvent; - WindowPtr pWin; - RREventPtr *pHead, pCur, pPrev; - - pRREvent = (RREventPtr) data; - pWin = pRREvent->window; - pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, EventType); - if (pHead) { - pPrev = 0; - for (pCur = *pHead; pCur && pCur != pRREvent; pCur=pCur->next) - pPrev = pCur; - if (pCur) - { - if (pPrev) - pPrev->next = pRREvent->next; - else - *pHead = pRREvent->next; - } - } - xfree ((pointer) pRREvent); - return 1; -} - -/*ARGSUSED*/ -static int -RRFreeEvents (pointer data, XID id) -{ - RREventPtr *pHead, pCur, pNext; - - pHead = (RREventPtr *) data; - for (pCur = *pHead; pCur; pCur = pNext) { - pNext = pCur->next; - FreeResource (pCur->clientResource, ClientType); - xfree ((pointer) pCur); - } - xfree ((pointer) pHead); - return 1; -} - -void -RRExtensionInit (void) -{ - ExtensionEntry *extEntry; - - if (RRNScreens == 0) return; - - RRClientPrivateIndex = AllocateClientPrivateIndex (); - if (!AllocateClientPrivate (RRClientPrivateIndex, - sizeof (RRClientRec) + - screenInfo.numScreens * sizeof (RRTimesRec))) - return; - if (!AddCallback (&ClientStateCallback, RRClientCallback, 0)) - return; - - ClientType = CreateNewResourceType(RRFreeClient); - if (!ClientType) - return; - EventType = CreateNewResourceType(RRFreeEvents); - if (!EventType) - return; - extEntry = AddExtension (RANDR_NAME, RRNumberEvents, RRNumberErrors, - ProcRRDispatch, SProcRRDispatch, - RRResetProc, StandardMinorOpcode); - if (!extEntry) - return; - RRReqCode = (CARD8) extEntry->base; - RRErrBase = extEntry->errorBase; - RREventBase = extEntry->eventBase; - EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr) - SRRScreenChangeNotifyEvent; - - return; -} - -int -TellChanged (WindowPtr pWin, pointer value) -{ - RREventPtr *pHead, pRREvent; - ClientPtr client; - xRRScreenChangeNotifyEvent se; - ScreenPtr pScreen = pWin->drawable.pScreen; - rrScrPriv(pScreen); - RRScreenSizePtr pSize; - WindowPtr pRoot = WindowTable[pScreen->myNum]; - - pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, EventType); - if (!pHead) - return WT_WALKCHILDREN; - - se.type = RRScreenChangeNotify + RREventBase; - se.rotation = (CARD8) pScrPriv->rotation; - se.timestamp = pScrPriv->lastSetTime.milliseconds; - se.configTimestamp = pScrPriv->lastConfigTime.milliseconds; - se.root = pRoot->drawable.id; - se.window = pWin->drawable.id; - se.subpixelOrder = PictureGetSubpixelOrder (pScreen); - if (pScrPriv->size >= 0) - { - pSize = &pScrPriv->pSizes[pScrPriv->size]; - se.sizeID = pSize->id; - se.widthInPixels = pSize->width; - se.heightInPixels = pSize->height; - se.widthInMillimeters = pSize->mmWidth; - se.heightInMillimeters = pSize->mmHeight; - } - else - { - /* - * This "shouldn't happen", but a broken DDX can - * forget to set the current configuration on GetInfo - */ - se.sizeID = 0xffff; - se.widthInPixels = 0; - se.heightInPixels = 0; - se.widthInMillimeters = 0; - se.heightInMillimeters = 0; - } - for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) - { - client = pRREvent->client; - if (client == serverClient || client->clientGone) - continue; - se.sequenceNumber = client->sequence; - if(pRREvent->mask & RRScreenChangeNotifyMask) - WriteEventsToClient (client, 1, (xEvent *) &se); - } - return WT_WALKCHILDREN; -} - -Bool -RRGetInfo (ScreenPtr pScreen) -{ - rrScrPriv (pScreen); - int i, j, k, l; - Bool changed; - Rotation rotations; - RRScreenSizePtr pSize; - RRScreenRatePtr pRate; - - for (i = 0; i < pScrPriv->nSizes; i++) - { - pSize = &pScrPriv->pSizes[i]; - pSize->oldReferenced = pSize->referenced; - pSize->referenced = FALSE; - for (k = 0; k < pSize->nRates; k++) - { - pRate = &pSize->pRates[k]; - pRate->oldReferenced = pRate->referenced; - pRate->referenced = FALSE; - } - } - if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations)) - return FALSE; - - changed = FALSE; - - /* - * Check whether anything changed and simultaneously generate - * the protocol id values for the objects - */ - if (rotations != pScrPriv->rotations) - { - pScrPriv->rotations = rotations; - changed = TRUE; - } - - j = 0; - for (i = 0; i < pScrPriv->nSizes; i++) - { - pSize = &pScrPriv->pSizes[i]; - if (pSize->oldReferenced != pSize->referenced) - changed = TRUE; - if (pSize->referenced) - pSize->id = j++; - l = 0; - for (k = 0; k < pSize->nRates; k++) - { - pRate = &pSize->pRates[k]; - if (pRate->oldReferenced != pRate->referenced) - changed = TRUE; - if (pRate->referenced) - l++; - } - pSize->nRatesInUse = l; - } - pScrPriv->nSizesInUse = j; - if (changed) - { - UpdateCurrentTime (); - pScrPriv->lastConfigTime = currentTime; - WalkTree (pScreen, TellChanged, (pointer) pScreen); - } - return TRUE; -} - -void -RRSendConfigNotify (ScreenPtr pScreen) -{ - WindowPtr pWin = WindowTable[pScreen->myNum]; - xEvent event; - - 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); -} - -static int -ProcRRQueryVersion (ClientPtr client) -{ - xRRQueryVersionReply rep; - register int n; - 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; - rep.majorVersion = RANDR_MAJOR; - rep.minorVersion = RANDR_MINOR; - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.majorVersion, n); - swapl(&rep.minorVersion, n); - } - WriteToClient(client, sizeof(xRRQueryVersionReply), (char *)&rep); - return (client->noClientException); -} - - -extern char *ConnectionInfo; - -static int padlength[4] = {0, 3, 2, 1}; - -void -RREditConnectionInfo (ScreenPtr pScreen) -{ - xConnSetup *connSetup; - char *vendor; - xPixmapFormat *formats; - xWindowRoot *root; - xDepth *depth; - xVisualType *visual; - int screen = 0; - int d; - - connSetup = (xConnSetup *) ConnectionInfo; - vendor = (char *) connSetup + sizeof (xConnSetup); - formats = (xPixmapFormat *) ((char *) vendor + - connSetup->nbytesVendor + - padlength[connSetup->nbytesVendor & 3]); - root = (xWindowRoot *) ((char *) formats + - sizeof (xPixmapFormat) * screenInfo.numPixmapFormats); - while (screen != pScreen->myNum) - { - depth = (xDepth *) ((char *) root + - sizeof (xWindowRoot)); - for (d = 0; d < root->nDepths; d++) - { - visual = (xVisualType *) ((char *) depth + - sizeof (xDepth)); - depth = (xDepth *) ((char *) visual + - depth->nVisuals * sizeof (xVisualType)); - } - root = (xWindowRoot *) ((char *) depth); - screen++; - } - root->pixWidth = pScreen->width; - root->pixHeight = pScreen->height; - root->mmWidth = pScreen->mmWidth; - root->mmHeight = pScreen->mmHeight; -} - -static int -ProcRRGetScreenInfo (ClientPtr client) -{ - REQUEST(xRRGetScreenInfoReq); - xRRGetScreenInfoReply rep; - WindowPtr pWin; - int n; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - CARD8 *extra; - int extraLen; - - REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); - pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, - SecurityReadAccess); - - if (!pWin) - return BadWindow; - - pScreen = pWin->drawable.pScreen; - pScrPriv = rrGetScrPriv(pScreen); - rep.pad = 0; - if (!pScrPriv) - { - 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; - extra = 0; - extraLen = 0; - } - else - { - int i, j; - xScreenSizes *size; - CARD16 *rates; - CARD8 *data8; - Bool has_rate = RRClientKnowsRates (client); - - RRGetInfo (pScreen); - - rep.type = X_Reply; - rep.setOfRotations = pScrPriv->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 = pScrPriv->rotation; - rep.nSizes = pScrPriv->nSizesInUse; - rep.rate = pScrPriv->rate; - rep.nrateEnts = 0; - if (has_rate) - { - for (i = 0; i < pScrPriv->nSizes; i++) - { - RRScreenSizePtr pSize = &pScrPriv->pSizes[i]; - if (pSize->referenced) - { - rep.nrateEnts += (1 + pSize->nRatesInUse); - } - } - } - - if (pScrPriv->size >= 0) - rep.sizeID = pScrPriv->pSizes[pScrPriv->size].id; - else - return BadImplementation; - - extraLen = (rep.nSizes * sizeof (xScreenSizes) + - rep.nrateEnts * sizeof (CARD16)); - - extra = (CARD8 *) xalloc (extraLen); - if (!extra) - return BadAlloc; - /* - * First comes the size information - */ - size = (xScreenSizes *) extra; - rates = (CARD16 *) (size + rep.nSizes); - for (i = 0; i < pScrPriv->nSizes; i++) - { - RRScreenSizePtr pSize = &pScrPriv->pSizes[i]; - if (pSize->referenced) - { - size->widthInPixels = pSize->width; - size->heightInPixels = pSize->height; - size->widthInMillimeters = pSize->mmWidth; - size->heightInMillimeters = pSize->mmHeight; - if (client->swapped) - { - swaps (&size->widthInPixels, n); - swaps (&size->heightInPixels, n); - swaps (&size->widthInMillimeters, n); - swaps (&size->heightInMillimeters, n); - } - size++; - if (has_rate) - { - *rates = pSize->nRatesInUse; - if (client->swapped) - { - swaps (rates, n); - } - rates++; - for (j = 0; j < pSize->nRates; j++) - { - RRScreenRatePtr pRate = &pSize->pRates[j]; - if (pRate->referenced) - { - *rates = pRate->rate; - if (client->swapped) - { - swaps (rates, n); - } - rates++; - } - } - } - } - } - data8 = (CARD8 *) rates; - - if (data8 - (CARD8 *) extra != extraLen) - FatalError ("RRGetScreenInfo bad extra len %d != %d\n", - data8 - (CARD8 *) extra, extraLen); - rep.length = (extraLen + 3) >> 2; - } - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.timestamp, n); - swaps(&rep.rotation, n); - swaps(&rep.nSizes, n); - swaps(&rep.sizeID, n); - swaps(&rep.rate, n); - swaps(&rep.nrateEnts, n); - } - WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *)&rep); - if (extraLen) - { - WriteToClient (client, extraLen, (char *) extra); - xfree (extra); - } - return (client->noClientException); -} - -static int -ProcRRSetScreenConfig (ClientPtr client) -{ - REQUEST(xRRSetScreenConfigReq); - xRRSetScreenConfigReply rep; - DrawablePtr pDraw; - int n; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - TimeStamp configTime; - TimeStamp time; - RRScreenSizePtr pSize; - int i; - Rotation rotation; - int rate; - short oldWidth, oldHeight; - Bool has_rate; - - UpdateCurrentTime (); - - if (RRClientKnowsRates (client)) - { - REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); - has_rate = TRUE; - } - else - { - REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); - has_rate = FALSE; - } - - SECURITY_VERIFY_DRAWABLE(pDraw, stuff->drawable, client, - SecurityWriteAccess); - - pScreen = pDraw->pScreen; - - pScrPriv= rrGetScrPriv(pScreen); - - time = ClientTimeToServerTime(stuff->timestamp); - configTime = ClientTimeToServerTime(stuff->configTimestamp); - - oldWidth = pScreen->width; - oldHeight = pScreen->height; - - if (!pScrPriv) - { - time = currentTime; - rep.status = RRSetConfigFailed; - goto sendReply; - } - if (!RRGetInfo (pScreen)) - return BadAlloc; - - /* - * if the client's config timestamp is not the same as the last config - * timestamp, then the config information isn't up-to-date and - * can't even be validated - */ - if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0) - { - rep.status = RRSetConfigInvalidConfigTime; - goto sendReply; - } - - /* - * Search for the requested size - */ - pSize = 0; - for (i = 0; i < pScrPriv->nSizes; i++) - { - pSize = &pScrPriv->pSizes[i]; - if (pSize->referenced && pSize->id == stuff->sizeID) - { - break; - } - } - if (i == pScrPriv->nSizes) - { - /* - * Invalid size ID - */ - client->errorValue = stuff->sizeID; - return BadValue; - } - - /* - * Validate requested rotation - */ - rotation = (Rotation) stuff->rotation; - - /* test the rotation bits only! */ - switch (rotation & 0xf) { - case RR_Rotate_0: - case RR_Rotate_90: - case RR_Rotate_180: - case RR_Rotate_270: - break; - default: - /* - * Invalid rotation - */ - client->errorValue = stuff->rotation; - return BadValue; - } - - if ((~pScrPriv->rotations) & rotation) - { - /* - * requested rotation or reflection not supported by screen - */ - client->errorValue = stuff->rotation; - return BadMatch; - } - - /* - * Validate requested refresh - */ - if (has_rate) - rate = (int) stuff->rate; - else - rate = 0; - - if (rate) - { - for (i = 0; i < pSize->nRates; i++) - { - RRScreenRatePtr pRate = &pSize->pRates[i]; - if (pRate->referenced && pRate->rate == rate) - break; - } - if (i == pSize->nRates) - { - /* - * Invalid rate - */ - client->errorValue = rate; - return BadValue; - } - } - - /* - * 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; - } - - /* - * call out to ddx routine to effect the change - */ - if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate, - pSize)) - { - /* - * unknown DDX failure, report to client - */ - rep.status = RRSetConfigFailed; - goto sendReply; - } - - /* - * set current extension configuration pointers - */ - RRSetCurrentConfig (pScreen, rotation, rate, pSize); - - /* - * Deliver ScreenChangeNotify events whenever - * the configuration is updated - */ - WalkTree (pScreen, TellChanged, (pointer) pScreen); - - /* - * Deliver ConfigureNotify events when root changes - * pixel size - */ - if (oldWidth != pScreen->width || oldHeight != pScreen->height) - RRSendConfigNotify (pScreen); - RREditConnectionInfo (pScreen); - - /* - * Fix pointer bounds and location - */ - ScreenRestructured (pScreen); - pScrPriv->lastSetTime = time; - - /* - * Report Success - */ - rep.status = RRSetConfigSuccess; - -sendReply: - - rep.type = X_Reply; - /* rep.status has already been filled in */ - rep.length = 0; - rep.sequenceNumber = client->sequence; - - rep.newTimestamp = pScrPriv->lastSetTime.milliseconds; - rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds; - rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id; - - if (client->swapped) - { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.newTimestamp, n); - swapl(&rep.newConfigTimestamp, n); - swapl(&rep.root, n); - } - WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *)&rep); - - return (client->noClientException); -} - -static int -ProcRRSelectInput (ClientPtr client) -{ - REQUEST(xRRSelectInputReq); - rrClientPriv(client); - RRTimesPtr pTimes; - WindowPtr pWin; - RREventPtr pRREvent, pNewRREvent, *pHead; - XID clientResource; - - REQUEST_SIZE_MATCH(xRRSelectInputReq); - pWin = SecurityLookupWindow (stuff->window, client, SecurityWriteAccess); - if (!pWin) - return BadWindow; - pHead = (RREventPtr *)SecurityLookupIDByType(client, - pWin->drawable.id, EventType, - SecurityWriteAccess); - - if (stuff->enable & (RRScreenChangeNotifyMask)) - { - ScreenPtr pScreen = pWin->drawable.pScreen; - rrScrPriv (pScreen); - - if (pHead) - { - /* check for existing entry. */ - for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) - if (pRREvent->client == client) - return Success; - } - - /* build the entry */ - pNewRREvent = (RREventPtr) xalloc (sizeof (RREventRec)); - if (!pNewRREvent) - return BadAlloc; - pNewRREvent->next = 0; - pNewRREvent->client = client; - pNewRREvent->window = pWin; - pNewRREvent->mask = stuff->enable; - /* - * add a resource that will be deleted when - * the client goes away - */ - clientResource = FakeClientID (client->index); - pNewRREvent->clientResource = clientResource; - if (!AddResource (clientResource, ClientType, (pointer)pNewRREvent)) - return BadAlloc; - /* - * create a resource to contain a pointer to the list - * of clients selecting input. This must be indirect as - * the list may be arbitrarily rearranged which cannot be - * done through the resource database. - */ - if (!pHead) - { - pHead = (RREventPtr *) xalloc (sizeof (RREventPtr)); - if (!pHead || - !AddResource (pWin->drawable.id, EventType, (pointer)pHead)) - { - FreeResource (clientResource, RT_NONE); - return BadAlloc; - } - *pHead = 0; - } - pNewRREvent->next = *pHead; - *pHead = pNewRREvent; - /* - * Now see if the client needs an event - */ - if (pScrPriv) - { - pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum]; - if (CompareTimeStamps (pTimes->setTime, - pScrPriv->lastSetTime) != 0 || - CompareTimeStamps (pTimes->configTime, - pScrPriv->lastConfigTime) != 0) - { - TellChanged (pWin, (pointer) pScreen); - } - } - } - else if (stuff->enable == xFalse) - { - /* delete the interest */ - if (pHead) { - pNewRREvent = 0; - for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) { - if (pRREvent->client == client) - break; - pNewRREvent = pRREvent; - } - if (pRREvent) { - FreeResource (pRREvent->clientResource, ClientType); - if (pNewRREvent) - pNewRREvent->next = pRREvent->next; - else - *pHead = pRREvent->next; - xfree (pRREvent); - } - } - } - else - { - client->errorValue = stuff->enable; - return BadValue; - } - return Success; -} - - -static int -ProcRRDispatch (ClientPtr client) -{ - REQUEST(xReq); - switch (stuff->data) - { - case X_RRQueryVersion: - return ProcRRQueryVersion(client); - case X_RRSetScreenConfig: - return ProcRRSetScreenConfig(client); - case X_RRSelectInput: - return ProcRRSelectInput(client); - case X_RRGetScreenInfo: - return ProcRRGetScreenInfo(client); - default: - return BadRequest; - } -} - -static int -SProcRRQueryVersion (ClientPtr client) -{ - register int n; - REQUEST(xRRQueryVersionReq); - - swaps(&stuff->length, n); - swapl(&stuff->majorVersion, n); - swapl(&stuff->minorVersion, n); - return ProcRRQueryVersion(client); -} - -static int -SProcRRGetScreenInfo (ClientPtr client) -{ - register int n; - REQUEST(xRRGetScreenInfoReq); - - swaps(&stuff->length, n); - swapl(&stuff->window, n); - return ProcRRGetScreenInfo(client); -} - -static int -SProcRRSetScreenConfig (ClientPtr client) -{ - register int n; - REQUEST(xRRSetScreenConfigReq); - - if (RRClientKnowsRates (client)) - { - REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); - swaps (&stuff->rate, n); - } - else - { - REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); - } - - swaps(&stuff->length, n); - swapl(&stuff->drawable, n); - swapl(&stuff->timestamp, n); - swaps(&stuff->sizeID, n); - swaps(&stuff->rotation, n); - return ProcRRSetScreenConfig(client); -} - -static int -SProcRRSelectInput (ClientPtr client) -{ - register int n; - REQUEST(xRRSelectInputReq); - - swaps(&stuff->length, n); - swapl(&stuff->window, n); - return ProcRRSelectInput(client); -} - - -static int -SProcRRDispatch (ClientPtr client) -{ - REQUEST(xReq); - switch (stuff->data) - { - case X_RRQueryVersion: - return SProcRRQueryVersion(client); - case X_RRSetScreenConfig: - return SProcRRSetScreenConfig(client); - case X_RRSelectInput: - return SProcRRSelectInput(client); - case X_RRGetScreenInfo: - return SProcRRGetScreenInfo(client); - default: - return BadRequest; - } -} - - -static Bool -RRScreenSizeMatches (RRScreenSizePtr a, - RRScreenSizePtr b) -{ - if (a->width != b->width) - return FALSE; - if (a->height != b->height) - return FALSE; - if (a->mmWidth != b->mmWidth) - return FALSE; - if (a->mmHeight != b->mmHeight) - return FALSE; - return TRUE; -} - -RRScreenSizePtr -RRRegisterSize (ScreenPtr pScreen, - short width, - short height, - short mmWidth, - short mmHeight) -{ - rrScrPriv (pScreen); - int i; - RRScreenSize tmp; - RRScreenSizePtr pNew; - - if (!pScrPriv) - return 0; - - /* - * FIXME: The compiler reports that field - * id is used uninitialized here. - */ - - tmp.id = 0; - - tmp.width = width; - tmp.height= height; - tmp.mmWidth = mmWidth; - tmp.mmHeight = mmHeight; - tmp.pRates = 0; - tmp.nRates = 0; - tmp.nRatesInUse = 0; - tmp.referenced = TRUE; - tmp.oldReferenced = FALSE; - for (i = 0; i < pScrPriv->nSizes; i++) - if (RRScreenSizeMatches (&tmp, &pScrPriv->pSizes[i])) - { - pScrPriv->pSizes[i].referenced = TRUE; - return &pScrPriv->pSizes[i]; - } - pNew = xrealloc (pScrPriv->pSizes, - (pScrPriv->nSizes + 1) * sizeof (RRScreenSize)); - if (!pNew) - return 0; - pNew[pScrPriv->nSizes++] = tmp; - pScrPriv->pSizes = pNew; - return &pNew[pScrPriv->nSizes-1]; -} - -Bool RRRegisterRate (ScreenPtr pScreen, - RRScreenSizePtr pSize, - int rate) -{ - rrScrPriv(pScreen); - int i; - RRScreenRatePtr pNew, pRate; - - if (!pScrPriv) - return FALSE; - - for (i = 0; i < pSize->nRates; i++) - { - pRate = &pSize->pRates[i]; - if (pRate->rate == rate) - { - pRate->referenced = TRUE; - return TRUE; - } - } - - pNew = xrealloc (pSize->pRates, - (pSize->nRates + 1) * sizeof (RRScreenRate)); - if (!pNew) - return FALSE; - pRate = &pNew[pSize->nRates++]; - pRate->rate = rate; - pRate->referenced = TRUE; - pRate->oldReferenced = FALSE; - pSize->pRates = pNew; - return TRUE; -} - -void -RRSetCurrentConfig (ScreenPtr pScreen, - Rotation rotation, - int rate, - RRScreenSizePtr pSize) -{ - rrScrPriv (pScreen); - - if (!pScrPriv) - return; - - pScrPriv->rotation = rotation; - pScrPriv->size = pSize - pScrPriv->pSizes; - pScrPriv->rate = rate; -} - -#endif /* #ifdef NXAGENT_UPGRADE */ diff --git a/programs/Xserver/hw/nxagent/NXrandr.c.NX.original b/programs/Xserver/hw/nxagent/NXrandr.c.NX.original deleted file mode 100644 index d593fa6..0000000 --- a/programs/Xserver/hw/nxagent/NXrandr.c.NX.original +++ /dev/null @@ -1,1229 +0,0 @@ -#ifdef NXAGENT_UPGRADE - -#include "X/NXrandr.c" - -#else - -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */ -/* */ -/* NXAGENT, NX protocol compression and NX extensions to this software */ -/* are copyright of NoMachine. Redistribution and use of the present */ -/* software is allowed according to terms specified in the file LICENSE */ -/* which comes in the source distribution. */ -/* */ -/* Check http://www.nomachine.com/licensing.html for applicability. */ -/* */ -/* NX and NoMachine are trademarks of Medialogic S.p.A. */ -/* */ -/* All rights reserved. */ -/* */ -/**************************************************************************/ - -/* - * $XFree86: xc/programs/Xserver/randr/randr.c,v 1.19 2003/02/08 03:52:30 dawes Exp $ - * - * Copyright � 2000, Compaq Computer Corporation, - * Copyright � 2002, Hewlett Packard, 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 Compaq or HP not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. HP makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL HP - * 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. - * - * Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc. - */ - - -#define NEED_REPLIES -#define NEED_EVENTS -#include "X.h" -#include "Xproto.h" -#include "misc.h" -#include "os.h" -#include "dixstruct.h" -#include "resource.h" -#include "scrnintstr.h" -#include "windowstr.h" -#include "pixmapstr.h" -#include "extnsionst.h" -#include "servermd.h" -#include "randr.h" -#include "randrproto.h" -#include "../../randr/randrstr.h" -#include "render.h" /* we share subpixel order information */ -#include "picturestr.h" -#include "Xfuncproto.h" -#ifdef EXTMODULE -#include "xf86_ansic.h" -#endif - -#define RR_VALIDATE -int RRGeneration; -int RRNScreens; - -static int ProcRRQueryVersion (ClientPtr pClient); -static int ProcRRDispatch (ClientPtr pClient); -static int SProcRRDispatch (ClientPtr pClient); -static int SProcRRQueryVersion (ClientPtr pClient); - -#define wrap(priv,real,mem,func) {\ - priv->mem = real->mem; \ - real->mem = func; \ -} - -#define unwrap(priv,real,mem) {\ - real->mem = priv->mem; \ -} - -static CARD8 RRReqCode; -static int RRErrBase; -static int RREventBase; -static RESTYPE ClientType, EventType; /* resource types for event masks */ -static int RRClientPrivateIndex; - -typedef struct _RRTimes { - TimeStamp setTime; - TimeStamp configTime; -} RRTimesRec, *RRTimesPtr; - -typedef struct _RRClient { - int major_version; - int minor_version; -/* RRTimesRec times[0]; */ -} RRClientRec, *RRClientPtr; - -/* - * each window has a list of clients requesting - * RRNotify events. Each client has a resource - * for each window it selects RRNotify input for, - * this resource is used to delete the RRNotifyRec - * entry from the per-window queue. - */ - -typedef struct _RREvent *RREventPtr; - -typedef struct _RREvent { - RREventPtr next; - ClientPtr client; - WindowPtr window; - XID clientResource; - int mask; -} RREventRec; - -int rrPrivIndex = -1; - -#define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr) -#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient) - -static Bool -RRClientKnowsRates (ClientPtr pClient) -{ - rrClientPriv(pClient); - - return (pRRClient->major_version > 1 || - (pRRClient->major_version == 1 && pRRClient->minor_version >= 1)); -} - -static void -RRClientCallback (CallbackListPtr *list, - pointer closure, - pointer data) -{ - NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; - ClientPtr pClient = clientinfo->client; - rrClientPriv(pClient); - RRTimesPtr pTimes = (RRTimesPtr) (pRRClient + 1); - int i; - - pRRClient->major_version = 0; - pRRClient->minor_version = 0; - for (i = 0; i < screenInfo.numScreens; i++) - { - ScreenPtr pScreen = screenInfo.screens[i]; - rrScrPriv(pScreen); - - if (pScrPriv) - { - pTimes[i].setTime = pScrPriv->lastSetTime; - pTimes[i].configTime = pScrPriv->lastConfigTime; - } - } -} - -static void -RRResetProc (ExtensionEntry *extEntry) -{ -} - -static Bool -RRCloseScreen (int i, ScreenPtr pScreen) -{ - rrScrPriv(pScreen); - - unwrap (pScrPriv, pScreen, CloseScreen); - if (pScrPriv->pSizes) - xfree (pScrPriv->pSizes); - xfree (pScrPriv); - RRNScreens -= 1; /* ok, one fewer screen with RandR running */ - return (*pScreen->CloseScreen) (i, pScreen); -} - -static void -SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from, - xRRScreenChangeNotifyEvent *to) -{ - to->type = from->type; - to->rotation = from->rotation; - cpswaps(from->sequenceNumber, to->sequenceNumber); - cpswapl(from->timestamp, to->timestamp); - cpswapl(from->configTimestamp, to->configTimestamp); - cpswapl(from->root, to->root); - cpswapl(from->window, to->window); - cpswaps(from->sizeID, to->sizeID); - 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); -} - -Bool RRScreenInit(ScreenPtr pScreen) -{ - rrScrPrivPtr pScrPriv; - - if (RRGeneration != serverGeneration) - { - if ((rrPrivIndex = AllocateScreenPrivateIndex()) < 0) - return FALSE; - RRGeneration = serverGeneration; - } - - pScrPriv = (rrScrPrivPtr) xalloc (sizeof (rrScrPrivRec)); - if (!pScrPriv) - return FALSE; - - SetRRScreen(pScreen, pScrPriv); - - /* - * Calling function best set these function vectors - */ - pScrPriv->rrSetConfig = 0; - pScrPriv->rrGetInfo = 0; - /* - * This value doesn't really matter -- any client must call - * GetScreenInfo before reading it which will automatically update - * the time - */ - pScrPriv->lastSetTime = currentTime; - pScrPriv->lastConfigTime = currentTime; - - wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen); - - pScrPriv->rotations = RR_Rotate_0; - - pScrPriv->nSizes = 0; - pScrPriv->nSizesInUse = 0; - pScrPriv->pSizes = 0; - - pScrPriv->rotation = RR_Rotate_0; - pScrPriv->size = -1; - - RRNScreens += 1; /* keep count of screens that implement randr */ - return TRUE; -} - -/*ARGSUSED*/ -static int -RRFreeClient (pointer data, XID id) -{ - RREventPtr pRREvent; - WindowPtr pWin; - RREventPtr *pHead, pCur, pPrev; - - pRREvent = (RREventPtr) data; - pWin = pRREvent->window; - pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, EventType); - if (pHead) { - pPrev = 0; - for (pCur = *pHead; pCur && pCur != pRREvent; pCur=pCur->next) - pPrev = pCur; - if (pCur) - { - if (pPrev) - pPrev->next = pRREvent->next; - else - *pHead = pRREvent->next; - } - } - xfree ((pointer) pRREvent); - return 1; -} - -/*ARGSUSED*/ -static int -RRFreeEvents (pointer data, XID id) -{ - RREventPtr *pHead, pCur, pNext; - - pHead = (RREventPtr *) data; - for (pCur = *pHead; pCur; pCur = pNext) { - pNext = pCur->next; - FreeResource (pCur->clientResource, ClientType); - xfree ((pointer) pCur); - } - xfree ((pointer) pHead); - return 1; -} - -void -RRExtensionInit (void) -{ - ExtensionEntry *extEntry; - - if (RRNScreens == 0) return; - - RRClientPrivateIndex = AllocateClientPrivateIndex (); - if (!AllocateClientPrivate (RRClientPrivateIndex, - sizeof (RRClientRec) + - screenInfo.numScreens * sizeof (RRTimesRec))) - return; - if (!AddCallback (&ClientStateCallback, RRClientCallback, 0)) - return; - - ClientType = CreateNewResourceType(RRFreeClient); - if (!ClientType) - return; - EventType = CreateNewResourceType(RRFreeEvents); - if (!EventType) - return; - extEntry = AddExtension (RANDR_NAME, RRNumberEvents, RRNumberErrors, - ProcRRDispatch, SProcRRDispatch, - RRResetProc, StandardMinorOpcode); - if (!extEntry) - return; - RRReqCode = (CARD8) extEntry->base; - RRErrBase = extEntry->errorBase; - RREventBase = extEntry->eventBase; - EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr) - SRRScreenChangeNotifyEvent; - - return; -} - -int -TellChanged (WindowPtr pWin, pointer value) -{ - RREventPtr *pHead, pRREvent; - ClientPtr client; - xRRScreenChangeNotifyEvent se; - ScreenPtr pScreen = pWin->drawable.pScreen; - rrScrPriv(pScreen); - RRScreenSizePtr pSize; - WindowPtr pRoot = WindowTable[pScreen->myNum]; - - pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, EventType); - if (!pHead) - return WT_WALKCHILDREN; - - se.type = RRScreenChangeNotify + RREventBase; - se.rotation = (CARD8) pScrPriv->rotation; - se.timestamp = pScrPriv->lastSetTime.milliseconds; - se.configTimestamp = pScrPriv->lastConfigTime.milliseconds; - se.root = pRoot->drawable.id; - se.window = pWin->drawable.id; - se.subpixelOrder = PictureGetSubpixelOrder (pScreen); - if (pScrPriv->size >= 0) - { - pSize = &pScrPriv->pSizes[pScrPriv->size]; - se.sizeID = pSize->id; - se.widthInPixels = pSize->width; - se.heightInPixels = pSize->height; - se.widthInMillimeters = pSize->mmWidth; - se.heightInMillimeters = pSize->mmHeight; - } - else - { - /* - * This "shouldn't happen", but a broken DDX can - * forget to set the current configuration on GetInfo - */ - se.sizeID = 0xffff; - se.widthInPixels = 0; - se.heightInPixels = 0; - se.widthInMillimeters = 0; - se.heightInMillimeters = 0; - } - for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) - { - client = pRREvent->client; - if (client == serverClient || client->clientGone) - continue; - se.sequenceNumber = client->sequence; - if(pRREvent->mask & RRScreenChangeNotifyMask) - WriteEventsToClient (client, 1, (xEvent *) &se); - } - return WT_WALKCHILDREN; -} - -Bool -RRGetInfo (ScreenPtr pScreen) -{ - rrScrPriv (pScreen); - int i, j, k, l; - Bool changed; - Rotation rotations; - RRScreenSizePtr pSize; - RRScreenRatePtr pRate; - - for (i = 0; i < pScrPriv->nSizes; i++) - { - pSize = &pScrPriv->pSizes[i]; - pSize->oldReferenced = pSize->referenced; - pSize->referenced = FALSE; - for (k = 0; k < pSize->nRates; k++) - { - pRate = &pSize->pRates[k]; - pRate->oldReferenced = pRate->referenced; - pRate->referenced = FALSE; - } - } - if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations)) - return FALSE; - - changed = FALSE; - - /* - * Check whether anything changed and simultaneously generate - * the protocol id values for the objects - */ - if (rotations != pScrPriv->rotations) - { - pScrPriv->rotations = rotations; - changed = TRUE; - } - - j = 0; - for (i = 0; i < pScrPriv->nSizes; i++) - { - pSize = &pScrPriv->pSizes[i]; - if (pSize->oldReferenced != pSize->referenced) - changed = TRUE; - if (pSize->referenced) - pSize->id = j++; - l = 0; - for (k = 0; k < pSize->nRates; k++) - { - pRate = &pSize->pRates[k]; - if (pRate->oldReferenced != pRate->referenced) - changed = TRUE; - if (pRate->referenced) - l++; - } - pSize->nRatesInUse = l; - } - pScrPriv->nSizesInUse = j; - if (changed) - { - UpdateCurrentTime (); - pScrPriv->lastConfigTime = currentTime; - WalkTree (pScreen, TellChanged, (pointer) pScreen); - } - return TRUE; -} - -void -RRSendConfigNotify (ScreenPtr pScreen) -{ - WindowPtr pWin = WindowTable[pScreen->myNum]; - xEvent event; - - 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); -} - -static int -ProcRRQueryVersion (ClientPtr client) -{ - xRRQueryVersionReply rep; - register int n; - 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; - rep.majorVersion = RANDR_MAJOR; - rep.minorVersion = RANDR_MINOR; - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.majorVersion, n); - swapl(&rep.minorVersion, n); - } - WriteToClient(client, sizeof(xRRQueryVersionReply), (char *)&rep); - return (client->noClientException); -} - - -extern char *ConnectionInfo; - -static int padlength[4] = {0, 3, 2, 1}; - -void -RREditConnectionInfo (ScreenPtr pScreen) -{ - xConnSetup *connSetup; - char *vendor; - xPixmapFormat *formats; - xWindowRoot *root; - xDepth *depth; - xVisualType *visual; - int screen = 0; - int d; - - connSetup = (xConnSetup *) ConnectionInfo; - vendor = (char *) connSetup + sizeof (xConnSetup); - formats = (xPixmapFormat *) ((char *) vendor + - connSetup->nbytesVendor + - padlength[connSetup->nbytesVendor & 3]); - root = (xWindowRoot *) ((char *) formats + - sizeof (xPixmapFormat) * screenInfo.numPixmapFormats); - while (screen != pScreen->myNum) - { - depth = (xDepth *) ((char *) root + - sizeof (xWindowRoot)); - for (d = 0; d < root->nDepths; d++) - { - visual = (xVisualType *) ((char *) depth + - sizeof (xDepth)); - depth = (xDepth *) ((char *) visual + - depth->nVisuals * sizeof (xVisualType)); - } - root = (xWindowRoot *) ((char *) depth); - screen++; - } - root->pixWidth = pScreen->width; - root->pixHeight = pScreen->height; - root->mmWidth = pScreen->mmWidth; - root->mmHeight = pScreen->mmHeight; -} - -static int -ProcRRGetScreenInfo (ClientPtr client) -{ - REQUEST(xRRGetScreenInfoReq); - xRRGetScreenInfoReply rep; - WindowPtr pWin; - int n; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - CARD8 *extra; - int extraLen; - - REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); - pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, - SecurityReadAccess); - - if (!pWin) - return BadWindow; - - pScreen = pWin->drawable.pScreen; - pScrPriv = rrGetScrPriv(pScreen); - rep.pad = 0; - if (!pScrPriv) - { - 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; - extra = 0; - extraLen = 0; - } - else - { - int i, j; - xScreenSizes *size; - CARD16 *rates; - CARD8 *data8; - Bool has_rate = RRClientKnowsRates (client); - - RRGetInfo (pScreen); - - rep.type = X_Reply; - rep.setOfRotations = pScrPriv->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 = pScrPriv->rotation; - rep.nSizes = pScrPriv->nSizesInUse; - rep.rate = pScrPriv->rate; - rep.nrateEnts = 0; - if (has_rate) - { - for (i = 0; i < pScrPriv->nSizes; i++) - { - RRScreenSizePtr pSize = &pScrPriv->pSizes[i]; - if (pSize->referenced) - { - rep.nrateEnts += (1 + pSize->nRatesInUse); - } - } - } - - if (pScrPriv->size >= 0) - rep.sizeID = pScrPriv->pSizes[pScrPriv->size].id; - else - return BadImplementation; - - extraLen = (rep.nSizes * sizeof (xScreenSizes) + - rep.nrateEnts * sizeof (CARD16)); - - extra = (CARD8 *) xalloc (extraLen); - if (!extra) - return BadAlloc; - /* - * First comes the size information - */ - size = (xScreenSizes *) extra; - rates = (CARD16 *) (size + rep.nSizes); - for (i = 0; i < pScrPriv->nSizes; i++) - { - RRScreenSizePtr pSize = &pScrPriv->pSizes[i]; - if (pSize->referenced) - { - size->widthInPixels = pSize->width; - size->heightInPixels = pSize->height; - size->widthInMillimeters = pSize->mmWidth; - size->heightInMillimeters = pSize->mmHeight; - if (client->swapped) - { - swaps (&size->widthInPixels, n); - swaps (&size->heightInPixels, n); - swaps (&size->widthInMillimeters, n); - swaps (&size->heightInMillimeters, n); - } - size++; - if (has_rate) - { - *rates = pSize->nRatesInUse; - if (client->swapped) - { - swaps (rates, n); - } - rates++; - for (j = 0; j < pSize->nRates; j++) - { - RRScreenRatePtr pRate = &pSize->pRates[j]; - if (pRate->referenced) - { - *rates = pRate->rate; - if (client->swapped) - { - swaps (rates, n); - } - rates++; - } - } - } - } - } - data8 = (CARD8 *) rates; - - if (data8 - (CARD8 *) extra != extraLen) - FatalError ("RRGetScreenInfo bad extra len %d != %d\n", - data8 - (CARD8 *) extra, extraLen); - rep.length = (extraLen + 3) >> 2; - } - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.timestamp, n); - swaps(&rep.rotation, n); - swaps(&rep.nSizes, n); - swaps(&rep.sizeID, n); - swaps(&rep.rate, n); - swaps(&rep.nrateEnts, n); - } - WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *)&rep); - if (extraLen) - { - WriteToClient (client, extraLen, (char *) extra); - xfree (extra); - } - return (client->noClientException); -} - -static int -ProcRRSetScreenConfig (ClientPtr client) -{ - REQUEST(xRRSetScreenConfigReq); - xRRSetScreenConfigReply rep; - DrawablePtr pDraw; - int n; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - TimeStamp configTime; - TimeStamp time; - RRScreenSizePtr pSize; - int i; - Rotation rotation; - int rate; - short oldWidth, oldHeight; - Bool has_rate; - - UpdateCurrentTime (); - - if (RRClientKnowsRates (client)) - { - REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); - has_rate = TRUE; - } - else - { - REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); - has_rate = FALSE; - } - - SECURITY_VERIFY_DRAWABLE(pDraw, stuff->drawable, client, - SecurityWriteAccess); - - pScreen = pDraw->pScreen; - - pScrPriv= rrGetScrPriv(pScreen); - - time = ClientTimeToServerTime(stuff->timestamp); - configTime = ClientTimeToServerTime(stuff->configTimestamp); - - oldWidth = pScreen->width; - oldHeight = pScreen->height; - - if (!pScrPriv) - { - time = currentTime; - rep.status = RRSetConfigFailed; - goto sendReply; - } - if (!RRGetInfo (pScreen)) - return BadAlloc; - - /* - * if the client's config timestamp is not the same as the last config - * timestamp, then the config information isn't up-to-date and - * can't even be validated - */ - if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0) - { - rep.status = RRSetConfigInvalidConfigTime; - goto sendReply; - } - - /* - * Search for the requested size - */ - pSize = 0; - for (i = 0; i < pScrPriv->nSizes; i++) - { - pSize = &pScrPriv->pSizes[i]; - if (pSize->referenced && pSize->id == stuff->sizeID) - { - break; - } - } - if (i == pScrPriv->nSizes) - { - /* - * Invalid size ID - */ - client->errorValue = stuff->sizeID; - return BadValue; - } - - /* - * Validate requested rotation - */ - rotation = (Rotation) stuff->rotation; - - /* test the rotation bits only! */ - switch (rotation & 0xf) { - case RR_Rotate_0: - case RR_Rotate_90: - case RR_Rotate_180: - case RR_Rotate_270: - break; - default: - /* - * Invalid rotation - */ - client->errorValue = stuff->rotation; - return BadValue; - } - - if ((~pScrPriv->rotations) & rotation) - { - /* - * requested rotation or reflection not supported by screen - */ - client->errorValue = stuff->rotation; - return BadMatch; - } - - /* - * Validate requested refresh - */ - if (has_rate) - rate = (int) stuff->rate; - else - rate = 0; - - if (rate) - { - for (i = 0; i < pSize->nRates; i++) - { - RRScreenRatePtr pRate = &pSize->pRates[i]; - if (pRate->referenced && pRate->rate == rate) - break; - } - if (i == pSize->nRates) - { - /* - * Invalid rate - */ - client->errorValue = rate; - return BadValue; - } - } - - /* - * 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; - } - - /* - * call out to ddx routine to effect the change - */ - if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate, - pSize)) - { - /* - * unknown DDX failure, report to client - */ - rep.status = RRSetConfigFailed; - goto sendReply; - } - - /* - * set current extension configuration pointers - */ - RRSetCurrentConfig (pScreen, rotation, rate, pSize); - - /* - * Deliver ScreenChangeNotify events whenever - * the configuration is updated - */ - WalkTree (pScreen, TellChanged, (pointer) pScreen); - - /* - * Deliver ConfigureNotify events when root changes - * pixel size - */ - if (oldWidth != pScreen->width || oldHeight != pScreen->height) - RRSendConfigNotify (pScreen); - RREditConnectionInfo (pScreen); - - /* - * Fix pointer bounds and location - */ - ScreenRestructured (pScreen); - pScrPriv->lastSetTime = time; - - /* - * Report Success - */ - rep.status = RRSetConfigSuccess; - -sendReply: - - rep.type = X_Reply; - /* rep.status has already been filled in */ - rep.length = 0; - rep.sequenceNumber = client->sequence; - - rep.newTimestamp = pScrPriv->lastSetTime.milliseconds; - rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds; - rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id; - - if (client->swapped) - { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.newTimestamp, n); - swapl(&rep.newConfigTimestamp, n); - swapl(&rep.root, n); - } - WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *)&rep); - - return (client->noClientException); -} - -static int -ProcRRSelectInput (ClientPtr client) -{ - REQUEST(xRRSelectInputReq); - rrClientPriv(client); - RRTimesPtr pTimes; - WindowPtr pWin; - RREventPtr pRREvent, pNewRREvent, *pHead; - XID clientResource; - - REQUEST_SIZE_MATCH(xRRSelectInputReq); - pWin = SecurityLookupWindow (stuff->window, client, SecurityWriteAccess); - if (!pWin) - return BadWindow; - pHead = (RREventPtr *)SecurityLookupIDByType(client, - pWin->drawable.id, EventType, - SecurityWriteAccess); - - if (stuff->enable & (RRScreenChangeNotifyMask)) - { - ScreenPtr pScreen = pWin->drawable.pScreen; - rrScrPriv (pScreen); - - if (pHead) - { - /* check for existing entry. */ - for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) - if (pRREvent->client == client) - return Success; - } - - /* build the entry */ - pNewRREvent = (RREventPtr) xalloc (sizeof (RREventRec)); - if (!pNewRREvent) - return BadAlloc; - pNewRREvent->next = 0; - pNewRREvent->client = client; - pNewRREvent->window = pWin; - pNewRREvent->mask = stuff->enable; - /* - * add a resource that will be deleted when - * the client goes away - */ - clientResource = FakeClientID (client->index); - pNewRREvent->clientResource = clientResource; - if (!AddResource (clientResource, ClientType, (pointer)pNewRREvent)) - return BadAlloc; - /* - * create a resource to contain a pointer to the list - * of clients selecting input. This must be indirect as - * the list may be arbitrarily rearranged which cannot be - * done through the resource database. - */ - if (!pHead) - { - pHead = (RREventPtr *) xalloc (sizeof (RREventPtr)); - if (!pHead || - !AddResource (pWin->drawable.id, EventType, (pointer)pHead)) - { - FreeResource (clientResource, RT_NONE); - return BadAlloc; - } - *pHead = 0; - } - pNewRREvent->next = *pHead; - *pHead = pNewRREvent; - /* - * Now see if the client needs an event - */ - if (pScrPriv) - { - pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum]; - if (CompareTimeStamps (pTimes->setTime, - pScrPriv->lastSetTime) != 0 || - CompareTimeStamps (pTimes->configTime, - pScrPriv->lastConfigTime) != 0) - { - TellChanged (pWin, (pointer) pScreen); - } - } - } - else if (stuff->enable == xFalse) - { - /* delete the interest */ - if (pHead) { - pNewRREvent = 0; - for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) { - if (pRREvent->client == client) - break; - pNewRREvent = pRREvent; - } - if (pRREvent) { - FreeResource (pRREvent->clientResource, ClientType); - if (pNewRREvent) - pNewRREvent->next = pRREvent->next; - else - *pHead = pRREvent->next; - xfree (pRREvent); - } - } - } - else - { - client->errorValue = stuff->enable; - return BadValue; - } - return Success; -} - - -static int -ProcRRDispatch (ClientPtr client) -{ - REQUEST(xReq); - switch (stuff->data) - { - case X_RRQueryVersion: - return ProcRRQueryVersion(client); - case X_RRSetScreenConfig: - return ProcRRSetScreenConfig(client); - case X_RRSelectInput: - return ProcRRSelectInput(client); - case X_RRGetScreenInfo: - return ProcRRGetScreenInfo(client); - default: - return BadRequest; - } -} - -static int -SProcRRQueryVersion (ClientPtr client) -{ - register int n; - REQUEST(xRRQueryVersionReq); - - swaps(&stuff->length, n); - swapl(&stuff->majorVersion, n); - swapl(&stuff->minorVersion, n); - return ProcRRQueryVersion(client); -} - -static int -SProcRRGetScreenInfo (ClientPtr client) -{ - register int n; - REQUEST(xRRGetScreenInfoReq); - - swaps(&stuff->length, n); - swapl(&stuff->window, n); - return ProcRRGetScreenInfo(client); -} - -static int -SProcRRSetScreenConfig (ClientPtr client) -{ - register int n; - REQUEST(xRRSetScreenConfigReq); - - if (RRClientKnowsRates (client)) - { - REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); - swaps (&stuff->rate, n); - } - else - { - REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); - } - - swaps(&stuff->length, n); - swapl(&stuff->drawable, n); - swapl(&stuff->timestamp, n); - swaps(&stuff->sizeID, n); - swaps(&stuff->rotation, n); - return ProcRRSetScreenConfig(client); -} - -static int -SProcRRSelectInput (ClientPtr client) -{ - register int n; - REQUEST(xRRSelectInputReq); - - swaps(&stuff->length, n); - swapl(&stuff->window, n); - return ProcRRSelectInput(client); -} - - -static int -SProcRRDispatch (ClientPtr client) -{ - REQUEST(xReq); - switch (stuff->data) - { - case X_RRQueryVersion: - return SProcRRQueryVersion(client); - case X_RRSetScreenConfig: - return SProcRRSetScreenConfig(client); - case X_RRSelectInput: - return SProcRRSelectInput(client); - case X_RRGetScreenInfo: - return SProcRRGetScreenInfo(client); - default: - return BadRequest; - } -} - - -static Bool -RRScreenSizeMatches (RRScreenSizePtr a, - RRScreenSizePtr b) -{ - if (a->width != b->width) - return FALSE; - if (a->height != b->height) - return FALSE; - if (a->mmWidth != b->mmWidth) - return FALSE; - if (a->mmHeight != b->mmHeight) - return FALSE; - return TRUE; -} - -RRScreenSizePtr -RRRegisterSize (ScreenPtr pScreen, - short width, - short height, - short mmWidth, - short mmHeight) -{ - rrScrPriv (pScreen); - int i; - RRScreenSize tmp; - RRScreenSizePtr pNew; - - if (!pScrPriv) - return 0; - - /* - * FIXME: The compiler reports that field - * id is used uninitialized here. - */ - - tmp.id = 0; - - tmp.width = width; - tmp.height= height; - tmp.mmWidth = mmWidth; - tmp.mmHeight = mmHeight; - tmp.pRates = 0; - tmp.nRates = 0; - tmp.nRatesInUse = 0; - tmp.referenced = TRUE; - tmp.oldReferenced = FALSE; - for (i = 0; i < pScrPriv->nSizes; i++) - if (RRScreenSizeMatches (&tmp, &pScrPriv->pSizes[i])) - { - pScrPriv->pSizes[i].referenced = TRUE; - return &pScrPriv->pSizes[i]; - } - pNew = xrealloc (pScrPriv->pSizes, - (pScrPriv->nSizes + 1) * sizeof (RRScreenSize)); - if (!pNew) - return 0; - pNew[pScrPriv->nSizes++] = tmp; - pScrPriv->pSizes = pNew; - return &pNew[pScrPriv->nSizes-1]; -} - -Bool RRRegisterRate (ScreenPtr pScreen, - RRScreenSizePtr pSize, - int rate) -{ - rrScrPriv(pScreen); - int i; - RRScreenRatePtr pNew, pRate; - - if (!pScrPriv) - return FALSE; - - for (i = 0; i < pSize->nRates; i++) - { - pRate = &pSize->pRates[i]; - if (pRate->rate == rate) - { - pRate->referenced = TRUE; - return TRUE; - } - } - - pNew = xrealloc (pSize->pRates, - (pSize->nRates + 1) * sizeof (RRScreenRate)); - if (!pNew) - return FALSE; - pRate = &pNew[pSize->nRates++]; - pRate->rate = rate; - pRate->referenced = TRUE; - pRate->oldReferenced = FALSE; - pSize->pRates = pNew; - return TRUE; -} - -void -RRSetCurrentConfig (ScreenPtr pScreen, - Rotation rotation, - int rate, - RRScreenSizePtr pSize) -{ - rrScrPriv (pScreen); - - if (!pScrPriv) - return; - - pScrPriv->rotation = rotation; - pScrPriv->size = pSize - pScrPriv->pSizes; - pScrPriv->rate = rate; -} - -#endif /* #ifdef NXAGENT_UPGRADE */ diff --git a/programs/Xserver/hw/nxagent/NXrandr.c.XF86.original b/programs/Xserver/hw/nxagent/NXrandr.c.XF86.original deleted file mode 100644 index 666605e..0000000 --- a/programs/Xserver/hw/nxagent/NXrandr.c.XF86.original +++ /dev/null @@ -1,1197 +0,0 @@ -/* - * $XFree86: xc/programs/Xserver/randr/randr.c,v 1.19 2003/02/08 03:52:30 dawes Exp $ - * - * Copyright � 2000, Compaq Computer Corporation, - * Copyright � 2002, Hewlett Packard, 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 Compaq or HP not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. HP makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL HP - * 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. - * - * Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc. - */ - - -#define NEED_REPLIES -#define NEED_EVENTS -#include "X.h" -#include "Xproto.h" -#include "misc.h" -#include "os.h" -#include "dixstruct.h" -#include "resource.h" -#include "scrnintstr.h" -#include "windowstr.h" -#include "pixmapstr.h" -#include "extnsionst.h" -#include "servermd.h" -#include "randr.h" -#include "randrproto.h" -#include "randrstr.h" -#include "render.h" /* we share subpixel order information */ -#include "picturestr.h" -#include "Xfuncproto.h" -#ifdef EXTMODULE -#include "xf86_ansic.h" -#endif - -#define RR_VALIDATE -int RRGeneration; -int RRNScreens; - -static int ProcRRQueryVersion (ClientPtr pClient); -static int ProcRRDispatch (ClientPtr pClient); -static int SProcRRDispatch (ClientPtr pClient); -static int SProcRRQueryVersion (ClientPtr pClient); - -#define wrap(priv,real,mem,func) {\ - priv->mem = real->mem; \ - real->mem = func; \ -} - -#define unwrap(priv,real,mem) {\ - real->mem = priv->mem; \ -} - -static CARD8 RRReqCode; -static int RRErrBase; -static int RREventBase; -static RESTYPE ClientType, EventType; /* resource types for event masks */ -static int RRClientPrivateIndex; - -typedef struct _RRTimes { - TimeStamp setTime; - TimeStamp configTime; -} RRTimesRec, *RRTimesPtr; - -typedef struct _RRClient { - int major_version; - int minor_version; -/* RRTimesRec times[0]; */ -} RRClientRec, *RRClientPtr; - -/* - * each window has a list of clients requesting - * RRNotify events. Each client has a resource - * for each window it selects RRNotify input for, - * this resource is used to delete the RRNotifyRec - * entry from the per-window queue. - */ - -typedef struct _RREvent *RREventPtr; - -typedef struct _RREvent { - RREventPtr next; - ClientPtr client; - WindowPtr window; - XID clientResource; - int mask; -} RREventRec; - -int rrPrivIndex = -1; - -#define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr) -#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient) - -static Bool -RRClientKnowsRates (ClientPtr pClient) -{ - rrClientPriv(pClient); - - return (pRRClient->major_version > 1 || - (pRRClient->major_version == 1 && pRRClient->minor_version >= 1)); -} - -static void -RRClientCallback (CallbackListPtr *list, - pointer closure, - pointer data) -{ - NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; - ClientPtr pClient = clientinfo->client; - rrClientPriv(pClient); - RRTimesPtr pTimes = (RRTimesPtr) (pRRClient + 1); - int i; - - pRRClient->major_version = 0; - pRRClient->minor_version = 0; - for (i = 0; i < screenInfo.numScreens; i++) - { - ScreenPtr pScreen = screenInfo.screens[i]; - rrScrPriv(pScreen); - - if (pScrPriv) - { - pTimes[i].setTime = pScrPriv->lastSetTime; - pTimes[i].configTime = pScrPriv->lastConfigTime; - } - } -} - -static void -RRResetProc (ExtensionEntry *extEntry) -{ -} - -static Bool -RRCloseScreen (int i, ScreenPtr pScreen) -{ - rrScrPriv(pScreen); - - unwrap (pScrPriv, pScreen, CloseScreen); - if (pScrPriv->pSizes) - xfree (pScrPriv->pSizes); - xfree (pScrPriv); - RRNScreens -= 1; /* ok, one fewer screen with RandR running */ - return (*pScreen->CloseScreen) (i, pScreen); -} - -static void -SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from, - xRRScreenChangeNotifyEvent *to) -{ - to->type = from->type; - to->rotation = from->rotation; - cpswaps(from->sequenceNumber, to->sequenceNumber); - cpswapl(from->timestamp, to->timestamp); - cpswapl(from->configTimestamp, to->configTimestamp); - cpswapl(from->root, to->root); - cpswapl(from->window, to->window); - cpswaps(from->sizeID, to->sizeID); - 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); -} - -Bool RRScreenInit(ScreenPtr pScreen) -{ - rrScrPrivPtr pScrPriv; - - if (RRGeneration != serverGeneration) - { - if ((rrPrivIndex = AllocateScreenPrivateIndex()) < 0) - return FALSE; - RRGeneration = serverGeneration; - } - - pScrPriv = (rrScrPrivPtr) xalloc (sizeof (rrScrPrivRec)); - if (!pScrPriv) - return FALSE; - - SetRRScreen(pScreen, pScrPriv); - - /* - * Calling function best set these function vectors - */ - pScrPriv->rrSetConfig = 0; - pScrPriv->rrGetInfo = 0; - /* - * This value doesn't really matter -- any client must call - * GetScreenInfo before reading it which will automatically update - * the time - */ - pScrPriv->lastSetTime = currentTime; - pScrPriv->lastConfigTime = currentTime; - - wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen); - - pScrPriv->rotations = RR_Rotate_0; - - pScrPriv->nSizes = 0; - pScrPriv->nSizesInUse = 0; - pScrPriv->pSizes = 0; - - pScrPriv->rotation = RR_Rotate_0; - pScrPriv->size = -1; - - RRNScreens += 1; /* keep count of screens that implement randr */ - return TRUE; -} - -/*ARGSUSED*/ -static int -RRFreeClient (pointer data, XID id) -{ - RREventPtr pRREvent; - WindowPtr pWin; - RREventPtr *pHead, pCur, pPrev; - - pRREvent = (RREventPtr) data; - pWin = pRREvent->window; - pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, EventType); - if (pHead) { - pPrev = 0; - for (pCur = *pHead; pCur && pCur != pRREvent; pCur=pCur->next) - pPrev = pCur; - if (pCur) - { - if (pPrev) - pPrev->next = pRREvent->next; - else - *pHead = pRREvent->next; - } - } - xfree ((pointer) pRREvent); - return 1; -} - -/*ARGSUSED*/ -static int -RRFreeEvents (pointer data, XID id) -{ - RREventPtr *pHead, pCur, pNext; - - pHead = (RREventPtr *) data; - for (pCur = *pHead; pCur; pCur = pNext) { - pNext = pCur->next; - FreeResource (pCur->clientResource, ClientType); - xfree ((pointer) pCur); - } - xfree ((pointer) pHead); - return 1; -} - -void -RRExtensionInit (void) -{ - ExtensionEntry *extEntry; - - if (RRNScreens == 0) return; - - RRClientPrivateIndex = AllocateClientPrivateIndex (); - if (!AllocateClientPrivate (RRClientPrivateIndex, - sizeof (RRClientRec) + - screenInfo.numScreens * sizeof (RRTimesRec))) - return; - if (!AddCallback (&ClientStateCallback, RRClientCallback, 0)) - return; - - ClientType = CreateNewResourceType(RRFreeClient); - if (!ClientType) - return; - EventType = CreateNewResourceType(RRFreeEvents); - if (!EventType) - return; - extEntry = AddExtension (RANDR_NAME, RRNumberEvents, RRNumberErrors, - ProcRRDispatch, SProcRRDispatch, - RRResetProc, StandardMinorOpcode); - if (!extEntry) - return; - RRReqCode = (CARD8) extEntry->base; - RRErrBase = extEntry->errorBase; - RREventBase = extEntry->eventBase; - EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr) - SRRScreenChangeNotifyEvent; - - return; -} - -static int -TellChanged (WindowPtr pWin, pointer value) -{ - RREventPtr *pHead, pRREvent; - ClientPtr client; - xRRScreenChangeNotifyEvent se; - ScreenPtr pScreen = pWin->drawable.pScreen; - rrScrPriv(pScreen); - RRScreenSizePtr pSize; - WindowPtr pRoot = WindowTable[pScreen->myNum]; - - pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, EventType); - if (!pHead) - return WT_WALKCHILDREN; - - se.type = RRScreenChangeNotify + RREventBase; - se.rotation = (CARD8) pScrPriv->rotation; - se.timestamp = pScrPriv->lastSetTime.milliseconds; - se.configTimestamp = pScrPriv->lastConfigTime.milliseconds; - se.root = pRoot->drawable.id; - se.window = pWin->drawable.id; - se.subpixelOrder = PictureGetSubpixelOrder (pScreen); - if (pScrPriv->size >= 0) - { - pSize = &pScrPriv->pSizes[pScrPriv->size]; - se.sizeID = pSize->id; - se.widthInPixels = pSize->width; - se.heightInPixels = pSize->height; - se.widthInMillimeters = pSize->mmWidth; - se.heightInMillimeters = pSize->mmHeight; - } - else - { - /* - * This "shouldn't happen", but a broken DDX can - * forget to set the current configuration on GetInfo - */ - se.sizeID = 0xffff; - se.widthInPixels = 0; - se.heightInPixels = 0; - se.widthInMillimeters = 0; - se.heightInMillimeters = 0; - } - for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) - { - client = pRREvent->client; - if (client == serverClient || client->clientGone) - continue; - se.sequenceNumber = client->sequence; - if(pRREvent->mask & RRScreenChangeNotifyMask) - WriteEventsToClient (client, 1, (xEvent *) &se); - } - return WT_WALKCHILDREN; -} - -static Bool -RRGetInfo (ScreenPtr pScreen) -{ - rrScrPriv (pScreen); - int i, j, k, l; - Bool changed; - Rotation rotations; - RRScreenSizePtr pSize; - RRScreenRatePtr pRate; - - for (i = 0; i < pScrPriv->nSizes; i++) - { - pSize = &pScrPriv->pSizes[i]; - pSize->oldReferenced = pSize->referenced; - pSize->referenced = FALSE; - for (k = 0; k < pSize->nRates; k++) - { - pRate = &pSize->pRates[k]; - pRate->oldReferenced = pRate->referenced; - pRate->referenced = FALSE; - } - } - if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations)) - return FALSE; - - changed = FALSE; - - /* - * Check whether anything changed and simultaneously generate - * the protocol id values for the objects - */ - if (rotations != pScrPriv->rotations) - { - pScrPriv->rotations = rotations; - changed = TRUE; - } - - j = 0; - for (i = 0; i < pScrPriv->nSizes; i++) - { - pSize = &pScrPriv->pSizes[i]; - if (pSize->oldReferenced != pSize->referenced) - changed = TRUE; - if (pSize->referenced) - pSize->id = j++; - l = 0; - for (k = 0; k < pSize->nRates; k++) - { - pRate = &pSize->pRates[k]; - if (pRate->oldReferenced != pRate->referenced) - changed = TRUE; - if (pRate->referenced) - l++; - } - pSize->nRatesInUse = l; - } - pScrPriv->nSizesInUse = j; - if (changed) - { - UpdateCurrentTime (); - pScrPriv->lastConfigTime = currentTime; - WalkTree (pScreen, TellChanged, (pointer) pScreen); - } - return TRUE; -} - -static void -RRSendConfigNotify (ScreenPtr pScreen) -{ - WindowPtr pWin = WindowTable[pScreen->myNum]; - xEvent event; - - 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); -} - -static int -ProcRRQueryVersion (ClientPtr client) -{ - xRRQueryVersionReply rep; - register int n; - 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; - rep.majorVersion = RANDR_MAJOR; - rep.minorVersion = RANDR_MINOR; - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.majorVersion, n); - swapl(&rep.minorVersion, n); - } - WriteToClient(client, sizeof(xRRQueryVersionReply), (char *)&rep); - return (client->noClientException); -} - - -extern char *ConnectionInfo; - -static int padlength[4] = {0, 3, 2, 1}; - -static void -RREditConnectionInfo (ScreenPtr pScreen) -{ - xConnSetup *connSetup; - char *vendor; - xPixmapFormat *formats; - xWindowRoot *root; - xDepth *depth; - xVisualType *visual; - int screen = 0; - int d; - - connSetup = (xConnSetup *) ConnectionInfo; - vendor = (char *) connSetup + sizeof (xConnSetup); - formats = (xPixmapFormat *) ((char *) vendor + - connSetup->nbytesVendor + - padlength[connSetup->nbytesVendor & 3]); - root = (xWindowRoot *) ((char *) formats + - sizeof (xPixmapFormat) * screenInfo.numPixmapFormats); - while (screen != pScreen->myNum) - { - depth = (xDepth *) ((char *) root + - sizeof (xWindowRoot)); - for (d = 0; d < root->nDepths; d++) - { - visual = (xVisualType *) ((char *) depth + - sizeof (xDepth)); - depth = (xDepth *) ((char *) visual + - depth->nVisuals * sizeof (xVisualType)); - } - root = (xWindowRoot *) ((char *) depth); - screen++; - } - root->pixWidth = pScreen->width; - root->pixHeight = pScreen->height; - root->mmWidth = pScreen->mmWidth; - root->mmHeight = pScreen->mmHeight; -} - -static int -ProcRRGetScreenInfo (ClientPtr client) -{ - REQUEST(xRRGetScreenInfoReq); - xRRGetScreenInfoReply rep; - WindowPtr pWin; - int n; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - CARD8 *extra; - int extraLen; - - REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); - pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, - SecurityReadAccess); - - if (!pWin) - return BadWindow; - - pScreen = pWin->drawable.pScreen; - pScrPriv = rrGetScrPriv(pScreen); - rep.pad = 0; - if (!pScrPriv) - { - 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; - extra = 0; - extraLen = 0; - } - else - { - int i, j; - xScreenSizes *size; - CARD16 *rates; - CARD8 *data8; - Bool has_rate = RRClientKnowsRates (client); - - RRGetInfo (pScreen); - - rep.type = X_Reply; - rep.setOfRotations = pScrPriv->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 = pScrPriv->rotation; - rep.nSizes = pScrPriv->nSizesInUse; - rep.rate = pScrPriv->rate; - rep.nrateEnts = 0; - if (has_rate) - { - for (i = 0; i < pScrPriv->nSizes; i++) - { - RRScreenSizePtr pSize = &pScrPriv->pSizes[i]; - if (pSize->referenced) - { - rep.nrateEnts += (1 + pSize->nRatesInUse); - } - } - } - - if (pScrPriv->size >= 0) - rep.sizeID = pScrPriv->pSizes[pScrPriv->size].id; - else - return BadImplementation; - - extraLen = (rep.nSizes * sizeof (xScreenSizes) + - rep.nrateEnts * sizeof (CARD16)); - - extra = (CARD8 *) xalloc (extraLen); - if (!extra) - return BadAlloc; - /* - * First comes the size information - */ - size = (xScreenSizes *) extra; - rates = (CARD16 *) (size + rep.nSizes); - for (i = 0; i < pScrPriv->nSizes; i++) - { - RRScreenSizePtr pSize = &pScrPriv->pSizes[i]; - if (pSize->referenced) - { - size->widthInPixels = pSize->width; - size->heightInPixels = pSize->height; - size->widthInMillimeters = pSize->mmWidth; - size->heightInMillimeters = pSize->mmHeight; - if (client->swapped) - { - swaps (&size->widthInPixels, n); - swaps (&size->heightInPixels, n); - swaps (&size->widthInMillimeters, n); - swaps (&size->heightInMillimeters, n); - } - size++; - if (has_rate) - { - *rates = pSize->nRatesInUse; - if (client->swapped) - { - swaps (rates, n); - } - rates++; - for (j = 0; j < pSize->nRates; j++) - { - RRScreenRatePtr pRate = &pSize->pRates[j]; - if (pRate->referenced) - { - *rates = pRate->rate; - if (client->swapped) - { - swaps (rates, n); - } - rates++; - } - } - } - } - } - data8 = (CARD8 *) rates; - - if (data8 - (CARD8 *) extra != extraLen) - FatalError ("RRGetScreenInfo bad extra len %d != %d\n", - data8 - (CARD8 *) extra, extraLen); - rep.length = (extraLen + 3) >> 2; - } - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.timestamp, n); - swaps(&rep.rotation, n); - swaps(&rep.nSizes, n); - swaps(&rep.sizeID, n); - swaps(&rep.rate, n); - swaps(&rep.nrateEnts, n); - } - WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *)&rep); - if (extraLen) - { - WriteToClient (client, extraLen, (char *) extra); - xfree (extra); - } - return (client->noClientException); -} - -static int -ProcRRSetScreenConfig (ClientPtr client) -{ - REQUEST(xRRSetScreenConfigReq); - xRRSetScreenConfigReply rep; - DrawablePtr pDraw; - int n; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - TimeStamp configTime; - TimeStamp time; - RRScreenSizePtr pSize; - int i; - Rotation rotation; - int rate; - short oldWidth, oldHeight; - Bool has_rate; - - UpdateCurrentTime (); - - if (RRClientKnowsRates (client)) - { - REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); - has_rate = TRUE; - } - else - { - REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); - has_rate = FALSE; - } - - SECURITY_VERIFY_DRAWABLE(pDraw, stuff->drawable, client, - SecurityWriteAccess); - - pScreen = pDraw->pScreen; - - pScrPriv= rrGetScrPriv(pScreen); - - time = ClientTimeToServerTime(stuff->timestamp); - configTime = ClientTimeToServerTime(stuff->configTimestamp); - - oldWidth = pScreen->width; - oldHeight = pScreen->height; - - if (!pScrPriv) - { - time = currentTime; - rep.status = RRSetConfigFailed; - goto sendReply; - } - if (!RRGetInfo (pScreen)) - return BadAlloc; - - /* - * if the client's config timestamp is not the same as the last config - * timestamp, then the config information isn't up-to-date and - * can't even be validated - */ - if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0) - { - rep.status = RRSetConfigInvalidConfigTime; - goto sendReply; - } - - /* - * Search for the requested size - */ - pSize = 0; - for (i = 0; i < pScrPriv->nSizes; i++) - { - pSize = &pScrPriv->pSizes[i]; - if (pSize->referenced && pSize->id == stuff->sizeID) - { - break; - } - } - if (i == pScrPriv->nSizes) - { - /* - * Invalid size ID - */ - client->errorValue = stuff->sizeID; - return BadValue; - } - - /* - * Validate requested rotation - */ - rotation = (Rotation) stuff->rotation; - - /* test the rotation bits only! */ - switch (rotation & 0xf) { - case RR_Rotate_0: - case RR_Rotate_90: - case RR_Rotate_180: - case RR_Rotate_270: - break; - default: - /* - * Invalid rotation - */ - client->errorValue = stuff->rotation; - return BadValue; - } - - if ((~pScrPriv->rotations) & rotation) - { - /* - * requested rotation or reflection not supported by screen - */ - client->errorValue = stuff->rotation; - return BadMatch; - } - - /* - * Validate requested refresh - */ - if (has_rate) - rate = (int) stuff->rate; - else - rate = 0; - - if (rate) - { - for (i = 0; i < pSize->nRates; i++) - { - RRScreenRatePtr pRate = &pSize->pRates[i]; - if (pRate->referenced && pRate->rate == rate) - break; - } - if (i == pSize->nRates) - { - /* - * Invalid rate - */ - client->errorValue = rate; - return BadValue; - } - } - - /* - * 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; - } - - /* - * call out to ddx routine to effect the change - */ - if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate, - pSize)) - { - /* - * unknown DDX failure, report to client - */ - rep.status = RRSetConfigFailed; - goto sendReply; - } - - /* - * set current extension configuration pointers - */ - RRSetCurrentConfig (pScreen, rotation, rate, pSize); - - /* - * Deliver ScreenChangeNotify events whenever - * the configuration is updated - */ - WalkTree (pScreen, TellChanged, (pointer) pScreen); - - /* - * Deliver ConfigureNotify events when root changes - * pixel size - */ - if (oldWidth != pScreen->width || oldHeight != pScreen->height) - RRSendConfigNotify (pScreen); - RREditConnectionInfo (pScreen); - - /* - * Fix pointer bounds and location - */ - ScreenRestructured (pScreen); - pScrPriv->lastSetTime = time; - - /* - * Report Success - */ - rep.status = RRSetConfigSuccess; - -sendReply: - - rep.type = X_Reply; - /* rep.status has already been filled in */ - rep.length = 0; - rep.sequenceNumber = client->sequence; - - rep.newTimestamp = pScrPriv->lastSetTime.milliseconds; - rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds; - rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id; - - if (client->swapped) - { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.newTimestamp, n); - swapl(&rep.newConfigTimestamp, n); - swapl(&rep.root, n); - } - WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *)&rep); - - return (client->noClientException); -} - -static int -ProcRRSelectInput (ClientPtr client) -{ - REQUEST(xRRSelectInputReq); - rrClientPriv(client); - RRTimesPtr pTimes; - WindowPtr pWin; - RREventPtr pRREvent, pNewRREvent, *pHead; - XID clientResource; - - REQUEST_SIZE_MATCH(xRRSelectInputReq); - pWin = SecurityLookupWindow (stuff->window, client, SecurityWriteAccess); - if (!pWin) - return BadWindow; - pHead = (RREventPtr *)SecurityLookupIDByType(client, - pWin->drawable.id, EventType, - SecurityWriteAccess); - - if (stuff->enable & (RRScreenChangeNotifyMask)) - { - ScreenPtr pScreen = pWin->drawable.pScreen; - rrScrPriv (pScreen); - - if (pHead) - { - /* check for existing entry. */ - for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) - if (pRREvent->client == client) - return Success; - } - - /* build the entry */ - pNewRREvent = (RREventPtr) xalloc (sizeof (RREventRec)); - if (!pNewRREvent) - return BadAlloc; - pNewRREvent->next = 0; - pNewRREvent->client = client; - pNewRREvent->window = pWin; - pNewRREvent->mask = stuff->enable; - /* - * add a resource that will be deleted when - * the client goes away - */ - clientResource = FakeClientID (client->index); - pNewRREvent->clientResource = clientResource; - if (!AddResource (clientResource, ClientType, (pointer)pNewRREvent)) - return BadAlloc; - /* - * create a resource to contain a pointer to the list - * of clients selecting input. This must be indirect as - * the list may be arbitrarily rearranged which cannot be - * done through the resource database. - */ - if (!pHead) - { - pHead = (RREventPtr *) xalloc (sizeof (RREventPtr)); - if (!pHead || - !AddResource (pWin->drawable.id, EventType, (pointer)pHead)) - { - FreeResource (clientResource, RT_NONE); - return BadAlloc; - } - *pHead = 0; - } - pNewRREvent->next = *pHead; - *pHead = pNewRREvent; - /* - * Now see if the client needs an event - */ - if (pScrPriv) - { - pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum]; - if (CompareTimeStamps (pTimes->setTime, - pScrPriv->lastSetTime) != 0 || - CompareTimeStamps (pTimes->configTime, - pScrPriv->lastConfigTime) != 0) - { - TellChanged (pWin, (pointer) pScreen); - } - } - } - else if (stuff->enable == xFalse) - { - /* delete the interest */ - if (pHead) { - pNewRREvent = 0; - for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) { - if (pRREvent->client == client) - break; - pNewRREvent = pRREvent; - } - if (pRREvent) { - FreeResource (pRREvent->clientResource, ClientType); - if (pNewRREvent) - pNewRREvent->next = pRREvent->next; - else - *pHead = pRREvent->next; - xfree (pRREvent); - } - } - } - else - { - client->errorValue = stuff->enable; - return BadValue; - } - return Success; -} - - -static int -ProcRRDispatch (ClientPtr client) -{ - REQUEST(xReq); - switch (stuff->data) - { - case X_RRQueryVersion: - return ProcRRQueryVersion(client); - case X_RRSetScreenConfig: - return ProcRRSetScreenConfig(client); - case X_RRSelectInput: - return ProcRRSelectInput(client); - case X_RRGetScreenInfo: - return ProcRRGetScreenInfo(client); - default: - return BadRequest; - } -} - -static int -SProcRRQueryVersion (ClientPtr client) -{ - register int n; - REQUEST(xRRQueryVersionReq); - - swaps(&stuff->length, n); - swapl(&stuff->majorVersion, n); - swapl(&stuff->minorVersion, n); - return ProcRRQueryVersion(client); -} - -static int -SProcRRGetScreenInfo (ClientPtr client) -{ - register int n; - REQUEST(xRRGetScreenInfoReq); - - swaps(&stuff->length, n); - swapl(&stuff->window, n); - return ProcRRGetScreenInfo(client); -} - -static int -SProcRRSetScreenConfig (ClientPtr client) -{ - register int n; - REQUEST(xRRSetScreenConfigReq); - - if (RRClientKnowsRates (client)) - { - REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); - swaps (&stuff->rate, n); - } - else - { - REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); - } - - swaps(&stuff->length, n); - swapl(&stuff->drawable, n); - swapl(&stuff->timestamp, n); - swaps(&stuff->sizeID, n); - swaps(&stuff->rotation, n); - return ProcRRSetScreenConfig(client); -} - -static int -SProcRRSelectInput (ClientPtr client) -{ - register int n; - REQUEST(xRRSelectInputReq); - - swaps(&stuff->length, n); - swapl(&stuff->window, n); - return ProcRRSelectInput(client); -} - - -static int -SProcRRDispatch (ClientPtr client) -{ - REQUEST(xReq); - switch (stuff->data) - { - case X_RRQueryVersion: - return SProcRRQueryVersion(client); - case X_RRSetScreenConfig: - return SProcRRSetScreenConfig(client); - case X_RRSelectInput: - return SProcRRSelectInput(client); - case X_RRGetScreenInfo: - return SProcRRGetScreenInfo(client); - default: - return BadRequest; - } -} - - -static Bool -RRScreenSizeMatches (RRScreenSizePtr a, - RRScreenSizePtr b) -{ - if (a->width != b->width) - return FALSE; - if (a->height != b->height) - return FALSE; - if (a->mmWidth != b->mmWidth) - return FALSE; - if (a->mmHeight != b->mmHeight) - return FALSE; - return TRUE; -} - -RRScreenSizePtr -RRRegisterSize (ScreenPtr pScreen, - short width, - short height, - short mmWidth, - short mmHeight) -{ - rrScrPriv (pScreen); - int i; - RRScreenSize tmp; - RRScreenSizePtr pNew; - - if (!pScrPriv) - return 0; - - tmp.width = width; - tmp.height= height; - tmp.mmWidth = mmWidth; - tmp.mmHeight = mmHeight; - tmp.pRates = 0; - tmp.nRates = 0; - tmp.nRatesInUse = 0; - tmp.referenced = TRUE; - tmp.oldReferenced = FALSE; - for (i = 0; i < pScrPriv->nSizes; i++) - if (RRScreenSizeMatches (&tmp, &pScrPriv->pSizes[i])) - { - pScrPriv->pSizes[i].referenced = TRUE; - return &pScrPriv->pSizes[i]; - } - pNew = xrealloc (pScrPriv->pSizes, - (pScrPriv->nSizes + 1) * sizeof (RRScreenSize)); - if (!pNew) - return 0; - pNew[pScrPriv->nSizes++] = tmp; - pScrPriv->pSizes = pNew; - return &pNew[pScrPriv->nSizes-1]; -} - -Bool RRRegisterRate (ScreenPtr pScreen, - RRScreenSizePtr pSize, - int rate) -{ - rrScrPriv(pScreen); - int i; - RRScreenRatePtr pNew, pRate; - - if (!pScrPriv) - return FALSE; - - for (i = 0; i < pSize->nRates; i++) - { - pRate = &pSize->pRates[i]; - if (pRate->rate == rate) - { - pRate->referenced = TRUE; - return TRUE; - } - } - - pNew = xrealloc (pSize->pRates, - (pSize->nRates + 1) * sizeof (RRScreenRate)); - if (!pNew) - return FALSE; - pRate = &pNew[pSize->nRates++]; - pRate->rate = rate; - pRate->referenced = TRUE; - pRate->oldReferenced = FALSE; - pSize->pRates = pNew; - return TRUE; -} - -void -RRSetCurrentConfig (ScreenPtr pScreen, - Rotation rotation, - int rate, - RRScreenSizePtr pSize) -{ - rrScrPriv (pScreen); - - if (!pScrPriv) - return; - - pScrPriv->rotation = rotation; - pScrPriv->size = pSize - pScrPriv->pSizes; - pScrPriv->rate = rate; -} diff --git a/programs/Xserver/hw/nxagent/Reconnect.c b/programs/Xserver/hw/nxagent/Reconnect.c index b786602..90b8079 100644 --- a/programs/Xserver/hw/nxagent/Reconnect.c +++ b/programs/Xserver/hw/nxagent/Reconnect.c @@ -598,7 +598,8 @@ Bool nxagentReconnectSession(void) if (nxagentResizeDesktopAtStartup || nxagentOption(Rootless) == True) { - nxagentRRSetScreenConfig(nxagentDefaultScreen, nxagentOption(RootWidth), nxagentOption(RootHeight)); + nxagentChangeScreenConfig(0, nxagentOption(RootWidth), + nxagentOption(RootHeight), 0, 0); nxagentResizeDesktopAtStartup = False; } diff --git a/programs/Xserver/hw/nxagent/Screen.c b/programs/Xserver/hw/nxagent/Screen.c index 2919970..9a4f7ec 100644 --- a/programs/Xserver/hw/nxagent/Screen.c +++ b/programs/Xserver/hw/nxagent/Screen.c @@ -2137,8 +2137,8 @@ static void nxagentSetRootClip (ScreenPtr pScreen, Bool enable) if (anyMarked) (*pScreen->ValidateTree)(pWin, NullWindow, VTOther); } - - if (pWin->backStorage && + + if (pWin->backStorage && pOldClip && ((pWin->backingStore == Always) || WasViewable)) { if (!WasViewable) @@ -2283,6 +2283,52 @@ FIXME: We should try to restore the previously nxagentChangeOption(ViewportYSpan, nxagentOption(Height) - nxagentOption(RootHeight)); /* + * Change agent window size and size hints. + */ + + if ((nxagentOption(Fullscreen) == 0 && nxagentOption(AllScreens) == 0)) + { + sizeHints.flags = PPosition | PMinSize | PMaxSize; + sizeHints.x = nxagentOption(X); + sizeHints.y = nxagentOption(Y); + + sizeHints.min_width = MIN_NXAGENT_WIDTH; + sizeHints.min_height = MIN_NXAGENT_HEIGHT; + sizeHints.width = width; + sizeHints.height = height; + + if (nxagentOption(DesktopResize) == 1) + { + sizeHints.max_width = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)); + sizeHints.max_height = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)); + } + else + { + sizeHints.max_width = nxagentOption(RootWidth); + sizeHints.max_height = nxagentOption(RootHeight); + } + + if (nxagentUserGeometry.flag & XValue || nxagentUserGeometry.flag & YValue) + { + sizeHints.flags |= USPosition; + } + + if (nxagentUserGeometry.flag & WidthValue || nxagentUserGeometry.flag & HeightValue) + { + sizeHints.flags |= USSize; + } + + XSetWMNormalHints(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum], &sizeHints); + + XResizeWindow(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum], width, height); + + if (nxagentOption(Rootless) == 0) + { + XResizeWindow(nxagentDisplay, nxagentInputWindows[pScreen -> myNum], width, height); + } + } + + /* * Set properties for the agent root window. */ @@ -2671,9 +2717,12 @@ int nxagentShadowInit(ScreenPtr pScreen, WindowPtr pWin) nxagentShadowCreateMainWindow(pScreen, pWin, nxagentShadowWidth, nxagentShadowHeight); - nxagentShadowSetWindowsSize(); + if (nxagentRemoteMajor <= 3) + { + nxagentShadowSetWindowsSize(); - nxagentSetWMNormalHints(0); + nxagentSetWMNormalHints(0); + } XMapWindow(nxagentDisplay, nxagentDefaultWindows[0]); @@ -3470,118 +3519,123 @@ Bool nxagentReconnectScreen(void *p0) return True; } -int nxagentRRSetScreenConfig(ScreenPtr pScreen, int width, int height) -{ - rrScrPrivPtr pScrPriv; - RRScreenSizePtr pSize; - Rotation rotation; - int rate; - short oldWidth, oldHeight; - int mmWidth, mmHeight; - int oldSize; - RRScreenSizePtr oldSizes; +RRModePtr nxagentRRCustomMode = NULL; - pScrPriv = rrGetScrPriv(pScreen); +int nxagentChangeScreenConfig(int screen, int width, int height, int mmWidth, int mmHeight) +{ + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + RROutputPtr output; + RRCrtcPtr crtc; + RRModePtr mode; + xRRModeInfo modeInfo; + char name[100]; + int r, c, m; + int refresh = 60; + int doNotify = 1; + + if (WindowTable[screen] == NULL) + { + return 0; + } - oldWidth = pScreen->width; - oldHeight = pScreen->height; + UpdateCurrentTime(); - if (!pScrPriv) - { - return 1; - } + if (nxagentGrabServerInfo.grabstate == SERVER_GRABBED) + { + /* + * If any client grabbed the server it won't expect that screen + * configuration changes until it releases the grab. That could + * get an X error because available modes are chanded meanwhile. + */ - if (!RRGetInfo (pScreen)) - { - return 1; - } + #ifdef TEST + fprintf(stderr, "nxagentChangeScreenConfig: Cancel with grabbed server.\n"); + #endif - rotation = RR_Rotate_0; + return 0; + } - rate = 0; + pScreen = WindowTable[screen] -> drawable.pScreen; - mmWidth = (width * 254 + monitorResolution * 5) / (monitorResolution * 10); + #ifdef TEST + fprintf(stderr, "nxagentChangeScreenConfig: Changing config to %dx%d.\n", width, height); + #endif - if (mmWidth < 1) - { - mmWidth = 1; - } + r = nxagentResizeScreen(pScreen, width, height, mmWidth, mmHeight); - mmHeight = (height * 254 + monitorResolution * 5) / (monitorResolution * 10); + if (r != 0) + { + pScrPriv = rrGetScrPriv(pScreen); - if (mmHeight < 1) + if (pScrPriv) { - mmHeight = 1; - } - - pSize = xalloc(sizeof(RRScreenSize)); - - pSize -> width = width; - pSize -> height = height; - pSize -> mmWidth = mmWidth; - pSize -> mmHeight = mmHeight; + output = RRFirstOutput(pScreen); - /* - * call out to ddx routine to effect the change - */ - - if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate, - pSize)) - { - /* - * unknown DDX failure. - */ + if (output && output -> crtc) + { + crtc = output -> crtc; - xfree(pSize); + for (c = 0; c < pScrPriv -> numCrtcs; c++) + { + RRCrtcSet(pScrPriv -> crtcs[c], NULL, 0, 0, RR_Rotate_0, 0, NULL); + } - return 1; - } + memset(&modeInfo, '\0', sizeof(modeInfo)); + sprintf(name, "%dx%d", width, height); - /* - * TellChanged uses this privates. - */ + modeInfo.width = width; + modeInfo.height = height; + modeInfo.hTotal = width; + modeInfo.vTotal = height; + modeInfo.dotClock = ((CARD32) width * (CARD32) height * + (CARD32) refresh); + modeInfo.nameLength = strlen(name); - oldSize = pScrPriv->size; - oldSizes = pScrPriv->pSizes; + if (nxagentRRCustomMode != NULL) + { + RROutputDeleteUserMode(output, nxagentRRCustomMode); + FreeResource(nxagentRRCustomMode -> mode.id, 0); - pScrPriv->size = 0; - pScrPriv->pSizes = pSize; + if (crtc != NULL && crtc -> mode == nxagentRRCustomMode) + { + RRCrtcSet(crtc, NULL, 0, 0, RR_Rotate_0, 0, NULL); + } - /* - * Deliver ScreenChangeNotify events whenever - * the configuration is updated - */ + #ifdef TEST + fprintf(stderr, "nxagentChangeScreenConfig: " + "Going to destroy mode %p with refcnt %d.\n", + nxagentRRCustomMode, nxagentRRCustomMode->refcnt); + #endif - WalkTree (pScreen, TellChanged, (pointer) pScreen); + RRModeDestroy(nxagentRRCustomMode); + } - /* - * Deliver ConfigureNotify events when root changes - * pixel size - */ + nxagentRRCustomMode = RRModeGet(&modeInfo, name); - if (oldWidth != pScreen->width || oldHeight != pScreen->height) - { - RRSendConfigNotify (pScreen); - } + RROutputAddUserMode(output, nxagentRRCustomMode); - RREditConnectionInfo (pScreen); + RRCrtcSet(crtc, nxagentRRCustomMode, 0, 0, RR_Rotate_0, 1, &output); - /* - * Fix pointer bounds and location - */ + RROutputChanged(output, 1); - ScreenRestructured (pScreen); + doNotify = 0; + } - /* - * Restore old privates. - */ + pScrPriv -> lastSetTime = currentTime; - pScrPriv->pSizes = oldSizes; - pScrPriv->size = oldSize; + pScrPriv->changed = 1; + pScrPriv->configChanged = 1; + } - xfree(pSize); + if (doNotify +) + { + RRScreenSizeNotify(pScreen); + } + } - return 0; + return r; } void nxagentSaveAreas(PixmapPtr pPixmap, RegionPtr prgnSave, int xorg, int yorg, WindowPtr pWin) diff --git a/programs/Xserver/hw/nxagent/Screen.h b/programs/Xserver/hw/nxagent/Screen.h index 5b19577..aab3ba1 100644 --- a/programs/Xserver/hw/nxagent/Screen.h +++ b/programs/Xserver/hw/nxagent/Screen.h @@ -100,7 +100,7 @@ Bool nxagentMagicPixelZone(int x, int y); Bool nxagentResizeScreen(ScreenPtr pScreen, int width, int height, int mmWidth, int mmHeight); -int nxagentRRSetScreenConfig(ScreenPtr pScreen, int width, int height); +int nxagentChangeScreenConfig(int screen, int width, int height, int mmWidth, int mmHeight); extern Bool nxagentReconnectScreen(void *p0); diff --git a/programs/Xserver/hw/nxagent/Window.c b/programs/Xserver/hw/nxagent/Window.c index 3e6d41d..9881936 100644 --- a/programs/Xserver/hw/nxagent/Window.c +++ b/programs/Xserver/hw/nxagent/Window.c @@ -899,8 +899,8 @@ void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn) { if (nxagentOption(Shadow) == 0) { - nxagentRRSetScreenConfig(pScreen, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)), - HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay))); + nxagentChangeScreenConfig(0, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)), + HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)), 0, 0); } else { @@ -953,7 +953,8 @@ void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn) if (nxagentOption(Shadow) == 0) { - nxagentRRSetScreenConfig(pScreen, nxagentOption(RootWidth), nxagentOption(RootHeight)); + nxagentChangeScreenConfig(0, nxagentOption(RootWidth), + nxagentOption(RootHeight), 0, 0); } } diff --git a/programs/Xserver/hw/nxagent/X/NXdixfonts.c b/programs/Xserver/hw/nxagent/X/NXdixfonts.c index 04fc047..3234c99 100644 --- a/programs/Xserver/hw/nxagent/X/NXdixfonts.c +++ b/programs/Xserver/hw/nxagent/X/NXdixfonts.c @@ -148,7 +148,8 @@ static const char *_NXGetFontPath(const char *path) _NXGetFontPathError: - strcpy(_NXFontPath, path); + strncpy(_NXFontPath, path, 1023); + _NXFontPath[1023] = '\0'; #ifdef NX_TRANS_TEST fprintf(stderr, "_NXGetFontPath: Using default font path [%s].\n", _NXFontPath); diff --git a/programs/Xserver/hw/nxagent/X/NXrandr.c b/programs/Xserver/hw/nxagent/X/NXrandr.c deleted file mode 100644 index 5f460f2..0000000 --- a/programs/Xserver/hw/nxagent/X/NXrandr.c +++ /dev/null @@ -1,1344 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */ -/* */ -/* NXAGENT, NX protocol compression and NX extensions to this software */ -/* are copyright of NoMachine. Redistribution and use of the present */ -/* software is allowed according to terms specified in the file LICENSE */ -/* which comes in the source distribution. */ -/* */ -/* Check http://www.nomachine.com/licensing.html for applicability. */ -/* */ -/* NX and NoMachine are trademarks of Medialogic S.p.A. */ -/* */ -/* All rights reserved. */ -/* */ -/**************************************************************************/ - -/* - * $XFree86: xc/programs/Xserver/randr/randr.c,v 1.21tsi Exp $ - * - * Copyright © 2000, Compaq Computer Corporation, - * Copyright © 2002, Hewlett Packard, 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 Compaq or HP not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. HP makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL HP - * 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. - * - * Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc. - */ - - -#define NEED_REPLIES -#define NEED_EVENTS -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include <X11/X.h> -#include <X11/Xproto.h> -#include "misc.h" -#include "os.h" -#include "dixstruct.h" -#include "resource.h" -#include "scrnintstr.h" -#include "windowstr.h" -#include "pixmapstr.h" -#include "extnsionst.h" -#include "servermd.h" -#include <X11/extensions/randr.h> -#include <X11/extensions/randrproto.h> -#include "../../randr/randrstr.h" -#ifdef RENDER -#include <X11/extensions/render.h> /* we share subpixel order information */ -#include "picturestr.h" -#endif -#include <X11/Xfuncproto.h> -#ifdef EXTMODULE -#include "xf86_ansic.h" -#endif - -/* From render.h */ -#ifndef SubPixelUnknown -#define SubPixelUnknown 0 -#endif - -#define RR_VALIDATE -int RRGeneration; -int RRNScreens; - -static int ProcRRQueryVersion (ClientPtr pClient); -static int ProcRRDispatch (ClientPtr pClient); -static int SProcRRDispatch (ClientPtr pClient); -static int SProcRRQueryVersion (ClientPtr pClient); - -#define wrap(priv,real,mem,func) {\ - priv->mem = real->mem; \ - real->mem = func; \ -} - -#define unwrap(priv,real,mem) {\ - real->mem = priv->mem; \ -} - -#if 0 -static CARD8 RRReqCode; -static int RRErrBase; -#endif -static int RREventBase; -static RESTYPE ClientType, EventType; /* resource types for event masks */ -static int RRClientPrivateIndex; - -typedef struct _RRTimes { - TimeStamp setTime; - TimeStamp configTime; -} RRTimesRec, *RRTimesPtr; - -typedef struct _RRClient { - int major_version; - int minor_version; -/* RRTimesRec times[0]; */ -} RRClientRec, *RRClientPtr; - -/* - * each window has a list of clients requesting - * RRNotify events. Each client has a resource - * for each window it selects RRNotify input for, - * this resource is used to delete the RRNotifyRec - * entry from the per-window queue. - */ - -typedef struct _RREvent *RREventPtr; - -typedef struct _RREvent { - RREventPtr next; - ClientPtr client; - WindowPtr window; - XID clientResource; - int mask; -} RREventRec; - -int rrPrivIndex = -1; - -#define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr) -#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient) - -static Bool -RRClientKnowsRates (ClientPtr pClient) -{ - rrClientPriv(pClient); - - return (pRRClient->major_version > 1 || - (pRRClient->major_version == 1 && pRRClient->minor_version >= 1)); -} - -static void -RRClientCallback (CallbackListPtr *list, - pointer closure, - pointer data) -{ - NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; - ClientPtr pClient = clientinfo->client; - rrClientPriv(pClient); - RRTimesPtr pTimes = (RRTimesPtr) (pRRClient + 1); - int i; - - pRRClient->major_version = 0; - pRRClient->minor_version = 0; - for (i = 0; i < screenInfo.numScreens; i++) - { - ScreenPtr pScreen = screenInfo.screens[i]; - rrScrPriv(pScreen); - - if (pScrPriv) - { - pTimes[i].setTime = pScrPriv->lastSetTime; - pTimes[i].configTime = pScrPriv->lastConfigTime; - } - } -} - -static void -RRResetProc (ExtensionEntry *extEntry) -{ -} - -static Bool -RRCloseScreen (int i, ScreenPtr pScreen) -{ - rrScrPriv(pScreen); - - unwrap (pScrPriv, pScreen, CloseScreen); - if (pScrPriv->pSizes) - xfree (pScrPriv->pSizes); - xfree (pScrPriv); - RRNScreens -= 1; /* ok, one fewer screen with RandR running */ - return (*pScreen->CloseScreen) (i, pScreen); -} - -static void -SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from, - xRRScreenChangeNotifyEvent *to) -{ - to->type = from->type; - to->rotation = from->rotation; - cpswaps(from->sequenceNumber, to->sequenceNumber); - cpswapl(from->timestamp, to->timestamp); - cpswapl(from->configTimestamp, to->configTimestamp); - cpswapl(from->root, to->root); - cpswapl(from->window, to->window); - cpswaps(from->sizeID, to->sizeID); - 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); -} - -Bool RRScreenInit(ScreenPtr pScreen) -{ - rrScrPrivPtr pScrPriv; - - if (RRGeneration != serverGeneration) - { - if ((rrPrivIndex = AllocateScreenPrivateIndex()) < 0) - return FALSE; - RRGeneration = serverGeneration; - } - - pScrPriv = (rrScrPrivPtr) xalloc (sizeof (rrScrPrivRec)); - if (!pScrPriv) - return FALSE; - - SetRRScreen(pScreen, pScrPriv); - - /* - * Calling function best set these function vectors - */ - pScrPriv->rrSetConfig = 0; - pScrPriv->rrGetInfo = 0; - /* - * This value doesn't really matter -- any client must call - * GetScreenInfo before reading it which will automatically update - * the time - */ - pScrPriv->lastSetTime = currentTime; - pScrPriv->lastConfigTime = currentTime; - - wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen); - - pScrPriv->rotations = RR_Rotate_0; - - pScrPriv->nSizes = 0; - pScrPriv->nSizesInUse = 0; - pScrPriv->pSizes = 0; - - pScrPriv->rotation = RR_Rotate_0; - pScrPriv->size = -1; - - RRNScreens += 1; /* keep count of screens that implement randr */ - return TRUE; -} - -/*ARGSUSED*/ -static int -RRFreeClient (pointer data, XID id) -{ - RREventPtr pRREvent; - WindowPtr pWin; - RREventPtr *pHead, pCur, pPrev; - - pRREvent = (RREventPtr) data; - pWin = pRREvent->window; - pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, EventType); - if (pHead) { - pPrev = 0; - for (pCur = *pHead; pCur && pCur != pRREvent; pCur=pCur->next) - pPrev = pCur; - if (pCur) - { - if (pPrev) - pPrev->next = pRREvent->next; - else - *pHead = pRREvent->next; - } - } - xfree ((pointer) pRREvent); - return 1; -} - -/*ARGSUSED*/ -static int -RRFreeEvents (pointer data, XID id) -{ - RREventPtr *pHead, pCur, pNext; - - pHead = (RREventPtr *) data; - for (pCur = *pHead; pCur; pCur = pNext) { - pNext = pCur->next; - FreeResource (pCur->clientResource, ClientType); - xfree ((pointer) pCur); - } - xfree ((pointer) pHead); - return 1; -} - -void -RRExtensionInit (void) -{ - ExtensionEntry *extEntry; - - if (RRNScreens == 0) return; - - RRClientPrivateIndex = AllocateClientPrivateIndex (); - if (!AllocateClientPrivate (RRClientPrivateIndex, - sizeof (RRClientRec) + - screenInfo.numScreens * sizeof (RRTimesRec))) - return; - if (!AddCallback (&ClientStateCallback, RRClientCallback, 0)) - return; - - ClientType = CreateNewResourceType(RRFreeClient); - if (!ClientType) - return; - EventType = CreateNewResourceType(RRFreeEvents); - if (!EventType) - return; - extEntry = AddExtension (RANDR_NAME, RRNumberEvents, RRNumberErrors, - ProcRRDispatch, SProcRRDispatch, - RRResetProc, StandardMinorOpcode); - if (!extEntry) - return; -#if 0 - RRReqCode = (CARD8) extEntry->base; - RRErrBase = extEntry->errorBase; -#endif - RREventBase = extEntry->eventBase; - EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr) - SRRScreenChangeNotifyEvent; - - return; -} - -int -TellChanged (WindowPtr pWin, pointer value) -{ - RREventPtr *pHead, pRREvent; - ClientPtr client; - xRRScreenChangeNotifyEvent se; - ScreenPtr pScreen = pWin->drawable.pScreen; - rrScrPriv(pScreen); - RRScreenSizePtr pSize; - WindowPtr pRoot = WindowTable[pScreen->myNum]; - - pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, EventType); - if (!pHead) - return WT_WALKCHILDREN; - - se.type = RRScreenChangeNotify + RREventBase; - se.rotation = (CARD8) pScrPriv->rotation; - se.timestamp = pScrPriv->lastSetTime.milliseconds; - 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; -#endif - if (pScrPriv->size >= 0) - { - pSize = &pScrPriv->pSizes[pScrPriv->size]; - se.sizeID = pSize->id; - se.widthInPixels = pSize->width; - se.heightInPixels = pSize->height; - se.widthInMillimeters = pSize->mmWidth; - se.heightInMillimeters = pSize->mmHeight; - } - else - { - /* - * This "shouldn't happen", but a broken DDX can - * forget to set the current configuration on GetInfo - */ - se.sizeID = 0xffff; - se.widthInPixels = 0; - se.heightInPixels = 0; - se.widthInMillimeters = 0; - se.heightInMillimeters = 0; - } - for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) - { - client = pRREvent->client; - if (client == serverClient || client->clientGone) - continue; - se.sequenceNumber = client->sequence; - if(pRREvent->mask & RRScreenChangeNotifyMask) - WriteEventsToClient (client, 1, (xEvent *) &se); - } - return WT_WALKCHILDREN; -} - -Bool -RRGetInfo (ScreenPtr pScreen) -{ - rrScrPriv (pScreen); - int i, j, k, l; - Bool changed; - Rotation rotations; - RRScreenSizePtr pSize; - RRScreenRatePtr pRate; - - for (i = 0; i < pScrPriv->nSizes; i++) - { - pSize = &pScrPriv->pSizes[i]; - pSize->oldReferenced = pSize->referenced; - pSize->referenced = FALSE; - for (k = 0; k < pSize->nRates; k++) - { - pRate = &pSize->pRates[k]; - pRate->oldReferenced = pRate->referenced; - pRate->referenced = FALSE; - } - } - if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations)) - return FALSE; - - changed = FALSE; - - /* - * Check whether anything changed and simultaneously generate - * the protocol id values for the objects - */ - if (rotations != pScrPriv->rotations) - { - pScrPriv->rotations = rotations; - changed = TRUE; - } - - j = 0; - for (i = 0; i < pScrPriv->nSizes; i++) - { - pSize = &pScrPriv->pSizes[i]; - if (pSize->oldReferenced != pSize->referenced) - changed = TRUE; - if (pSize->referenced) - pSize->id = j++; - l = 0; - for (k = 0; k < pSize->nRates; k++) - { - pRate = &pSize->pRates[k]; - if (pRate->oldReferenced != pRate->referenced) - changed = TRUE; - if (pRate->referenced) - l++; - } - pSize->nRatesInUse = l; - } - pScrPriv->nSizesInUse = j; - if (changed) - { - UpdateCurrentTime (); - pScrPriv->lastConfigTime = currentTime; - WalkTree (pScreen, TellChanged, (pointer) pScreen); - } - return TRUE; -} - -void -RRSendConfigNotify (ScreenPtr pScreen) -{ - WindowPtr pWin = WindowTable[pScreen->myNum]; - xEvent event; - - 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); -} - -static int -ProcRRQueryVersion (ClientPtr client) -{ - xRRQueryVersionReply rep; - register int n; - 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; - rep.majorVersion = RANDR_MAJOR; - rep.minorVersion = RANDR_MINOR; - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.majorVersion, n); - swapl(&rep.minorVersion, n); - } - WriteToClient(client, sizeof(xRRQueryVersionReply), (char *)&rep); - return (client->noClientException); -} - - -extern char *ConnectionInfo; - -static int padlength[4] = {0, 3, 2, 1}; - -void -RREditConnectionInfo (ScreenPtr pScreen) -{ - xConnSetup *connSetup; - char *vendor; - xPixmapFormat *formats; - xWindowRoot *root; - xDepth *depth; - xVisualType *visual; - int screen = 0; - int d; - - connSetup = (xConnSetup *) ConnectionInfo; - vendor = (char *) connSetup + sizeof (xConnSetup); - formats = (xPixmapFormat *) ((char *) vendor + - connSetup->nbytesVendor + - padlength[connSetup->nbytesVendor & 3]); - root = (xWindowRoot *) ((char *) formats + - sizeof (xPixmapFormat) * screenInfo.numPixmapFormats); - while (screen != pScreen->myNum) - { - depth = (xDepth *) ((char *) root + - sizeof (xWindowRoot)); - for (d = 0; d < root->nDepths; d++) - { - visual = (xVisualType *) ((char *) depth + - sizeof (xDepth)); - depth = (xDepth *) ((char *) visual + - depth->nVisuals * sizeof (xVisualType)); - } - root = (xWindowRoot *) ((char *) depth); - screen++; - } - root->pixWidth = pScreen->width; - root->pixHeight = pScreen->height; - root->mmWidth = pScreen->mmWidth; - root->mmHeight = pScreen->mmHeight; -} - -static int -ProcRRGetScreenInfo (ClientPtr client) -{ - REQUEST(xRRGetScreenInfoReq); - xRRGetScreenInfoReply rep; - WindowPtr pWin; - int n; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - CARD8 *extra; - unsigned long extraLen; - - REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); - pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, - SecurityReadAccess); - - if (!pWin) - return BadWindow; - - pScreen = pWin->drawable.pScreen; - pScrPriv = rrGetScrPriv(pScreen); - rep.pad = 0; - if (!pScrPriv) - { - 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; - extra = 0; - extraLen = 0; - } - else - { - int i, j; - xScreenSizes *size; - CARD16 *rates; - CARD8 *data8; - Bool has_rate = RRClientKnowsRates (client); - - RRGetInfo (pScreen); - - rep.type = X_Reply; - rep.setOfRotations = pScrPriv->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 = pScrPriv->rotation; - rep.nSizes = pScrPriv->nSizesInUse; - rep.rate = pScrPriv->rate; - rep.nrateEnts = 0; - if (has_rate) - { - for (i = 0; i < pScrPriv->nSizes; i++) - { - RRScreenSizePtr pSize = &pScrPriv->pSizes[i]; - if (pSize->referenced) - { - rep.nrateEnts += (1 + pSize->nRatesInUse); - } - } - } - - if (pScrPriv->size >= 0) - rep.sizeID = pScrPriv->pSizes[pScrPriv->size].id; - else - return BadImplementation; - - extraLen = (rep.nSizes * sizeof (xScreenSizes) + - rep.nrateEnts * sizeof (CARD16)); - - extra = (CARD8 *) xalloc (extraLen); - if (!extra) - return BadAlloc; - /* - * First comes the size information - */ - size = (xScreenSizes *) extra; - rates = (CARD16 *) (size + rep.nSizes); - for (i = 0; i < pScrPriv->nSizes; i++) - { - RRScreenSizePtr pSize = &pScrPriv->pSizes[i]; - if (pSize->referenced) - { - size->widthInPixels = pSize->width; - size->heightInPixels = pSize->height; - size->widthInMillimeters = pSize->mmWidth; - size->heightInMillimeters = pSize->mmHeight; - if (client->swapped) - { - swaps (&size->widthInPixels, n); - swaps (&size->heightInPixels, n); - swaps (&size->widthInMillimeters, n); - swaps (&size->heightInMillimeters, n); - } - size++; - if (has_rate) - { - *rates = pSize->nRatesInUse; - if (client->swapped) - { - swaps (rates, n); - } - rates++; - for (j = 0; j < pSize->nRates; j++) - { - RRScreenRatePtr pRate = &pSize->pRates[j]; - if (pRate->referenced) - { - *rates = pRate->rate; - if (client->swapped) - { - swaps (rates, n); - } - rates++; - } - } - } - } - } - data8 = (CARD8 *) rates; - - if (data8 - (CARD8 *) extra != extraLen) - FatalError ("RRGetScreenInfo bad extra len %ld != %ld\n", - (unsigned long)(data8 - (CARD8 *) extra), extraLen); - rep.length = (extraLen + 3) >> 2; - } - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.timestamp, n); - swaps(&rep.rotation, n); - swaps(&rep.nSizes, n); - swaps(&rep.sizeID, n); - swaps(&rep.rate, n); - swaps(&rep.nrateEnts, n); - } - WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *)&rep); - if (extraLen) - { - WriteToClient (client, extraLen, (char *) extra); - xfree (extra); - } - return (client->noClientException); -} - -static int -ProcRRSetScreenConfig (ClientPtr client) -{ - REQUEST(xRRSetScreenConfigReq); - xRRSetScreenConfigReply rep; - DrawablePtr pDraw; - int n; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - TimeStamp configTime; - TimeStamp time; - RRScreenSizePtr pSize; - int i; - Rotation rotation; - int rate; - short oldWidth, oldHeight; - Bool has_rate; - - UpdateCurrentTime (); - - if (RRClientKnowsRates (client)) - { - REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); - has_rate = TRUE; - } - else - { - REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); - has_rate = FALSE; - } - - SECURITY_VERIFY_DRAWABLE(pDraw, stuff->drawable, client, - SecurityWriteAccess); - - pScreen = pDraw->pScreen; - - pScrPriv = rrGetScrPriv(pScreen); - - time = ClientTimeToServerTime(stuff->timestamp); - configTime = ClientTimeToServerTime(stuff->configTimestamp); - - oldWidth = pScreen->width; - oldHeight = pScreen->height; - - if (!pScrPriv) - { - time = currentTime; - rep.status = RRSetConfigFailed; - goto sendReply; - } - if (!RRGetInfo (pScreen)) - return BadAlloc; - - /* - * if the client's config timestamp is not the same as the last config - * timestamp, then the config information isn't up-to-date and - * can't even be validated - */ - if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0) - { - rep.status = RRSetConfigInvalidConfigTime; - goto sendReply; - } - - /* - * Search for the requested size - */ - pSize = 0; - for (i = 0; i < pScrPriv->nSizes; i++) - { - pSize = &pScrPriv->pSizes[i]; - if (pSize->referenced && pSize->id == stuff->sizeID) - { - break; - } - } - if (i == pScrPriv->nSizes) - { - /* - * Invalid size ID - */ - client->errorValue = stuff->sizeID; - return BadValue; - } - - /* - * Validate requested rotation - */ - rotation = (Rotation) stuff->rotation; - - /* test the rotation bits only! */ - switch (rotation & 0xf) { - case RR_Rotate_0: - case RR_Rotate_90: - case RR_Rotate_180: - case RR_Rotate_270: - break; - default: - /* - * Invalid rotation - */ - client->errorValue = stuff->rotation; - return BadValue; - } - - if ((~pScrPriv->rotations) & rotation) - { - /* - * requested rotation or reflection not supported by screen - */ - client->errorValue = stuff->rotation; - return BadMatch; - } - - /* - * Validate requested refresh - */ - if (has_rate) - rate = (int) stuff->rate; - else - rate = 0; - - if (rate) - { - for (i = 0; i < pSize->nRates; i++) - { - RRScreenRatePtr pRate = &pSize->pRates[i]; - if (pRate->referenced && pRate->rate == rate) - break; - } - if (i == pSize->nRates) - { - /* - * Invalid rate - */ - client->errorValue = rate; - return BadValue; - } - } - - /* - * 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; - } - - /* - * call out to ddx routine to effect the change - */ - if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate, - pSize)) - { - /* - * unknown DDX failure, report to client - */ - rep.status = RRSetConfigFailed; - goto sendReply; - } - - /* - * set current extension configuration pointers - */ - RRSetCurrentConfig (pScreen, rotation, rate, pSize); - - /* - * Deliver ScreenChangeNotify events whenever - * the configuration is updated - */ - WalkTree (pScreen, TellChanged, (pointer) pScreen); - - /* - * Deliver ConfigureNotify events when root changes - * pixel size - */ - if (oldWidth != pScreen->width || oldHeight != pScreen->height) - RRSendConfigNotify (pScreen); - RREditConnectionInfo (pScreen); - - /* - * Fix pointer bounds and location - */ - ScreenRestructured (pScreen); - pScrPriv->lastSetTime = time; - - /* - * Report Success - */ - rep.status = RRSetConfigSuccess; - -sendReply: - - rep.type = X_Reply; - /* rep.status has already been filled in */ - rep.length = 0; - rep.sequenceNumber = client->sequence; - - rep.newTimestamp = pScrPriv->lastSetTime.milliseconds; - rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds; - rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id; - - if (client->swapped) - { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.newTimestamp, n); - swapl(&rep.newConfigTimestamp, n); - swapl(&rep.root, n); - } - WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *)&rep); - - return (client->noClientException); -} - -int -RRSetScreenConfig (ScreenPtr pScreen, - Rotation rotation, - int rate, - RRScreenSizePtr pSize) -{ - rrScrPrivPtr pScrPriv; - int i; - short oldWidth, oldHeight; - - pScrPriv = rrGetScrPriv(pScreen); - - oldWidth = pScreen->width; - oldHeight = pScreen->height; - - if (!RRGetInfo (pScreen)) - return BadAlloc; - - /* - * Validate requested rotation - */ - - /* test the rotation bits only! */ - switch (rotation & 0xf) { - case RR_Rotate_0: - case RR_Rotate_90: - case RR_Rotate_180: - case RR_Rotate_270: - break; - default: - /* - * Invalid rotation - */ - return BadValue; - } - - if ((~pScrPriv->rotations) & rotation) - { - /* - * requested rotation or reflection not supported by screen - */ - return BadMatch; - } - - /* - * Validate requested refresh - */ - if (rate) - { - for (i = 0; i < pSize->nRates; i++) - { - RRScreenRatePtr pRate = &pSize->pRates[i]; - if (pRate->referenced && pRate->rate == rate) - break; - } - if (i == pSize->nRates) - { - /* - * Invalid rate - */ - return BadValue; - } - } - - /* - * call out to ddx routine to effect the change - */ - if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate, - pSize)) - { - /* - * unknown DDX failure, report to client - */ - return BadImplementation; - } - - /* - * set current extension configuration pointers - */ - RRSetCurrentConfig (pScreen, rotation, rate, pSize); - - /* - * Deliver ScreenChangeNotify events whenever - * the configuration is updated - */ - WalkTree (pScreen, TellChanged, (pointer) pScreen); - - /* - * Deliver ConfigureNotify events when root changes - * pixel size - */ - if (oldWidth != pScreen->width || oldHeight != pScreen->height) - RRSendConfigNotify (pScreen); - RREditConnectionInfo (pScreen); - - /* - * Fix pointer bounds and location - */ - ScreenRestructured (pScreen); - - return Success; -} - -static int -ProcRRSelectInput (ClientPtr client) -{ - REQUEST(xRRSelectInputReq); - rrClientPriv(client); - RRTimesPtr pTimes; - WindowPtr pWin; - RREventPtr pRREvent, pNewRREvent, *pHead; - XID clientResource; - - REQUEST_SIZE_MATCH(xRRSelectInputReq); - pWin = SecurityLookupWindow (stuff->window, client, SecurityWriteAccess); - if (!pWin) - return BadWindow; - pHead = (RREventPtr *)SecurityLookupIDByType(client, - pWin->drawable.id, EventType, - SecurityWriteAccess); - - if (stuff->enable & (RRScreenChangeNotifyMask)) - { - ScreenPtr pScreen = pWin->drawable.pScreen; - rrScrPriv (pScreen); - - if (pHead) - { - /* check for existing entry. */ - for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) - if (pRREvent->client == client) - return Success; - } - - /* build the entry */ - pNewRREvent = (RREventPtr) xalloc (sizeof (RREventRec)); - if (!pNewRREvent) - return BadAlloc; - pNewRREvent->next = 0; - pNewRREvent->client = client; - pNewRREvent->window = pWin; - pNewRREvent->mask = stuff->enable; - /* - * add a resource that will be deleted when - * the client goes away - */ - clientResource = FakeClientID (client->index); - pNewRREvent->clientResource = clientResource; - if (!AddResource (clientResource, ClientType, (pointer)pNewRREvent)) - return BadAlloc; - /* - * create a resource to contain a pointer to the list - * of clients selecting input. This must be indirect as - * the list may be arbitrarily rearranged which cannot be - * done through the resource database. - */ - if (!pHead) - { - pHead = (RREventPtr *) xalloc (sizeof (RREventPtr)); - if (!pHead || - !AddResource (pWin->drawable.id, EventType, (pointer)pHead)) - { - FreeResource (clientResource, RT_NONE); - return BadAlloc; - } - *pHead = 0; - } - pNewRREvent->next = *pHead; - *pHead = pNewRREvent; - /* - * Now see if the client needs an event - */ - if (pScrPriv) - { - pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum]; - if (CompareTimeStamps (pTimes->setTime, - pScrPriv->lastSetTime) != 0 || - CompareTimeStamps (pTimes->configTime, - pScrPriv->lastConfigTime) != 0) - { - TellChanged (pWin, (pointer) pScreen); - } - } - } - else if (stuff->enable == xFalse) - { - /* delete the interest */ - if (pHead) { - pNewRREvent = 0; - for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) { - if (pRREvent->client == client) - break; - pNewRREvent = pRREvent; - } - if (pRREvent) { - FreeResource (pRREvent->clientResource, ClientType); - if (pNewRREvent) - pNewRREvent->next = pRREvent->next; - else - *pHead = pRREvent->next; - xfree (pRREvent); - } - } - } - else - { - client->errorValue = stuff->enable; - return BadValue; - } - return Success; -} - - -static int -ProcRRDispatch (ClientPtr client) -{ - REQUEST(xReq); - switch (stuff->data) - { - case X_RRQueryVersion: - return ProcRRQueryVersion(client); - case X_RRSetScreenConfig: - return ProcRRSetScreenConfig(client); - case X_RRSelectInput: - return ProcRRSelectInput(client); - case X_RRGetScreenInfo: - return ProcRRGetScreenInfo(client); - default: - return BadRequest; - } -} - -static int -SProcRRQueryVersion (ClientPtr client) -{ - register int n; - REQUEST(xRRQueryVersionReq); - - swaps(&stuff->length, n); - swapl(&stuff->majorVersion, n); - swapl(&stuff->minorVersion, n); - return ProcRRQueryVersion(client); -} - -static int -SProcRRGetScreenInfo (ClientPtr client) -{ - register int n; - REQUEST(xRRGetScreenInfoReq); - - swaps(&stuff->length, n); - swapl(&stuff->window, n); - return ProcRRGetScreenInfo(client); -} - -static int -SProcRRSetScreenConfig (ClientPtr client) -{ - register int n; - REQUEST(xRRSetScreenConfigReq); - - if (RRClientKnowsRates (client)) - { - REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); - swaps (&stuff->rate, n); - } - else - { - REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); - } - - swaps(&stuff->length, n); - swapl(&stuff->drawable, n); - swapl(&stuff->timestamp, n); - swaps(&stuff->sizeID, n); - swaps(&stuff->rotation, n); - return ProcRRSetScreenConfig(client); -} - -static int -SProcRRSelectInput (ClientPtr client) -{ - register int n; - REQUEST(xRRSelectInputReq); - - swaps(&stuff->length, n); - swapl(&stuff->window, n); - return ProcRRSelectInput(client); -} - - -static int -SProcRRDispatch (ClientPtr client) -{ - REQUEST(xReq); - switch (stuff->data) - { - case X_RRQueryVersion: - return SProcRRQueryVersion(client); - case X_RRSetScreenConfig: - return SProcRRSetScreenConfig(client); - case X_RRSelectInput: - return SProcRRSelectInput(client); - case X_RRGetScreenInfo: - return SProcRRGetScreenInfo(client); - default: - return BadRequest; - } -} - - -static Bool -RRScreenSizeMatches (RRScreenSizePtr a, - RRScreenSizePtr b) -{ - if (a->width != b->width) - return FALSE; - if (a->height != b->height) - return FALSE; - if (a->mmWidth != b->mmWidth) - return FALSE; - if (a->mmHeight != b->mmHeight) - return FALSE; - return TRUE; -} - -RRScreenSizePtr -RRRegisterSize (ScreenPtr pScreen, - short width, - short height, - short mmWidth, - short mmHeight) -{ - rrScrPriv (pScreen); - int i; - RRScreenSize tmp; - RRScreenSizePtr pNew; - - if (!pScrPriv) - return 0; - - /* - * FIXME: The compiler reports that field - * id is used uninitialized here. - */ - - tmp.id = 0; - - tmp.width = width; - tmp.height= height; - tmp.mmWidth = mmWidth; - tmp.mmHeight = mmHeight; - tmp.pRates = 0; - tmp.nRates = 0; - tmp.nRatesInUse = 0; - tmp.referenced = TRUE; - tmp.oldReferenced = FALSE; - for (i = 0; i < pScrPriv->nSizes; i++) - if (RRScreenSizeMatches (&tmp, &pScrPriv->pSizes[i])) - { - pScrPriv->pSizes[i].referenced = TRUE; - return &pScrPriv->pSizes[i]; - } - pNew = xrealloc (pScrPriv->pSizes, - (pScrPriv->nSizes + 1) * sizeof (RRScreenSize)); - if (!pNew) - return 0; - pNew[pScrPriv->nSizes++] = tmp; - pScrPriv->pSizes = pNew; - return &pNew[pScrPriv->nSizes-1]; -} - -Bool RRRegisterRate (ScreenPtr pScreen, - RRScreenSizePtr pSize, - int rate) -{ - rrScrPriv(pScreen); - int i; - RRScreenRatePtr pNew, pRate; - - if (!pScrPriv) - return FALSE; - - for (i = 0; i < pSize->nRates; i++) - { - pRate = &pSize->pRates[i]; - if (pRate->rate == rate) - { - pRate->referenced = TRUE; - return TRUE; - } - } - - pNew = xrealloc (pSize->pRates, - (pSize->nRates + 1) * sizeof (RRScreenRate)); - if (!pNew) - return FALSE; - pRate = &pNew[pSize->nRates++]; - pRate->rate = rate; - pRate->referenced = TRUE; - pRate->oldReferenced = FALSE; - pSize->pRates = pNew; - return TRUE; -} - -void -RRSetCurrentConfig (ScreenPtr pScreen, - Rotation rotation, - int rate, - RRScreenSizePtr pSize) -{ - rrScrPriv (pScreen); - - if (!pScrPriv) - return; - - pScrPriv->rotation = rotation; - pScrPriv->size = pSize - pScrPriv->pSizes; - pScrPriv->rate = rate; -} - diff --git a/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original b/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original deleted file mode 100644 index 5f460f2..0000000 --- a/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original +++ /dev/null @@ -1,1344 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */ -/* */ -/* NXAGENT, NX protocol compression and NX extensions to this software */ -/* are copyright of NoMachine. Redistribution and use of the present */ -/* software is allowed according to terms specified in the file LICENSE */ -/* which comes in the source distribution. */ -/* */ -/* Check http://www.nomachine.com/licensing.html for applicability. */ -/* */ -/* NX and NoMachine are trademarks of Medialogic S.p.A. */ -/* */ -/* All rights reserved. */ -/* */ -/**************************************************************************/ - -/* - * $XFree86: xc/programs/Xserver/randr/randr.c,v 1.21tsi Exp $ - * - * Copyright © 2000, Compaq Computer Corporation, - * Copyright © 2002, Hewlett Packard, 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 Compaq or HP not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. HP makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL HP - * 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. - * - * Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc. - */ - - -#define NEED_REPLIES -#define NEED_EVENTS -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include <X11/X.h> -#include <X11/Xproto.h> -#include "misc.h" -#include "os.h" -#include "dixstruct.h" -#include "resource.h" -#include "scrnintstr.h" -#include "windowstr.h" -#include "pixmapstr.h" -#include "extnsionst.h" -#include "servermd.h" -#include <X11/extensions/randr.h> -#include <X11/extensions/randrproto.h> -#include "../../randr/randrstr.h" -#ifdef RENDER -#include <X11/extensions/render.h> /* we share subpixel order information */ -#include "picturestr.h" -#endif -#include <X11/Xfuncproto.h> -#ifdef EXTMODULE -#include "xf86_ansic.h" -#endif - -/* From render.h */ -#ifndef SubPixelUnknown -#define SubPixelUnknown 0 -#endif - -#define RR_VALIDATE -int RRGeneration; -int RRNScreens; - -static int ProcRRQueryVersion (ClientPtr pClient); -static int ProcRRDispatch (ClientPtr pClient); -static int SProcRRDispatch (ClientPtr pClient); -static int SProcRRQueryVersion (ClientPtr pClient); - -#define wrap(priv,real,mem,func) {\ - priv->mem = real->mem; \ - real->mem = func; \ -} - -#define unwrap(priv,real,mem) {\ - real->mem = priv->mem; \ -} - -#if 0 -static CARD8 RRReqCode; -static int RRErrBase; -#endif -static int RREventBase; -static RESTYPE ClientType, EventType; /* resource types for event masks */ -static int RRClientPrivateIndex; - -typedef struct _RRTimes { - TimeStamp setTime; - TimeStamp configTime; -} RRTimesRec, *RRTimesPtr; - -typedef struct _RRClient { - int major_version; - int minor_version; -/* RRTimesRec times[0]; */ -} RRClientRec, *RRClientPtr; - -/* - * each window has a list of clients requesting - * RRNotify events. Each client has a resource - * for each window it selects RRNotify input for, - * this resource is used to delete the RRNotifyRec - * entry from the per-window queue. - */ - -typedef struct _RREvent *RREventPtr; - -typedef struct _RREvent { - RREventPtr next; - ClientPtr client; - WindowPtr window; - XID clientResource; - int mask; -} RREventRec; - -int rrPrivIndex = -1; - -#define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr) -#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient) - -static Bool -RRClientKnowsRates (ClientPtr pClient) -{ - rrClientPriv(pClient); - - return (pRRClient->major_version > 1 || - (pRRClient->major_version == 1 && pRRClient->minor_version >= 1)); -} - -static void -RRClientCallback (CallbackListPtr *list, - pointer closure, - pointer data) -{ - NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; - ClientPtr pClient = clientinfo->client; - rrClientPriv(pClient); - RRTimesPtr pTimes = (RRTimesPtr) (pRRClient + 1); - int i; - - pRRClient->major_version = 0; - pRRClient->minor_version = 0; - for (i = 0; i < screenInfo.numScreens; i++) - { - ScreenPtr pScreen = screenInfo.screens[i]; - rrScrPriv(pScreen); - - if (pScrPriv) - { - pTimes[i].setTime = pScrPriv->lastSetTime; - pTimes[i].configTime = pScrPriv->lastConfigTime; - } - } -} - -static void -RRResetProc (ExtensionEntry *extEntry) -{ -} - -static Bool -RRCloseScreen (int i, ScreenPtr pScreen) -{ - rrScrPriv(pScreen); - - unwrap (pScrPriv, pScreen, CloseScreen); - if (pScrPriv->pSizes) - xfree (pScrPriv->pSizes); - xfree (pScrPriv); - RRNScreens -= 1; /* ok, one fewer screen with RandR running */ - return (*pScreen->CloseScreen) (i, pScreen); -} - -static void -SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from, - xRRScreenChangeNotifyEvent *to) -{ - to->type = from->type; - to->rotation = from->rotation; - cpswaps(from->sequenceNumber, to->sequenceNumber); - cpswapl(from->timestamp, to->timestamp); - cpswapl(from->configTimestamp, to->configTimestamp); - cpswapl(from->root, to->root); - cpswapl(from->window, to->window); - cpswaps(from->sizeID, to->sizeID); - 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); -} - -Bool RRScreenInit(ScreenPtr pScreen) -{ - rrScrPrivPtr pScrPriv; - - if (RRGeneration != serverGeneration) - { - if ((rrPrivIndex = AllocateScreenPrivateIndex()) < 0) - return FALSE; - RRGeneration = serverGeneration; - } - - pScrPriv = (rrScrPrivPtr) xalloc (sizeof (rrScrPrivRec)); - if (!pScrPriv) - return FALSE; - - SetRRScreen(pScreen, pScrPriv); - - /* - * Calling function best set these function vectors - */ - pScrPriv->rrSetConfig = 0; - pScrPriv->rrGetInfo = 0; - /* - * This value doesn't really matter -- any client must call - * GetScreenInfo before reading it which will automatically update - * the time - */ - pScrPriv->lastSetTime = currentTime; - pScrPriv->lastConfigTime = currentTime; - - wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen); - - pScrPriv->rotations = RR_Rotate_0; - - pScrPriv->nSizes = 0; - pScrPriv->nSizesInUse = 0; - pScrPriv->pSizes = 0; - - pScrPriv->rotation = RR_Rotate_0; - pScrPriv->size = -1; - - RRNScreens += 1; /* keep count of screens that implement randr */ - return TRUE; -} - -/*ARGSUSED*/ -static int -RRFreeClient (pointer data, XID id) -{ - RREventPtr pRREvent; - WindowPtr pWin; - RREventPtr *pHead, pCur, pPrev; - - pRREvent = (RREventPtr) data; - pWin = pRREvent->window; - pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, EventType); - if (pHead) { - pPrev = 0; - for (pCur = *pHead; pCur && pCur != pRREvent; pCur=pCur->next) - pPrev = pCur; - if (pCur) - { - if (pPrev) - pPrev->next = pRREvent->next; - else - *pHead = pRREvent->next; - } - } - xfree ((pointer) pRREvent); - return 1; -} - -/*ARGSUSED*/ -static int -RRFreeEvents (pointer data, XID id) -{ - RREventPtr *pHead, pCur, pNext; - - pHead = (RREventPtr *) data; - for (pCur = *pHead; pCur; pCur = pNext) { - pNext = pCur->next; - FreeResource (pCur->clientResource, ClientType); - xfree ((pointer) pCur); - } - xfree ((pointer) pHead); - return 1; -} - -void -RRExtensionInit (void) -{ - ExtensionEntry *extEntry; - - if (RRNScreens == 0) return; - - RRClientPrivateIndex = AllocateClientPrivateIndex (); - if (!AllocateClientPrivate (RRClientPrivateIndex, - sizeof (RRClientRec) + - screenInfo.numScreens * sizeof (RRTimesRec))) - return; - if (!AddCallback (&ClientStateCallback, RRClientCallback, 0)) - return; - - ClientType = CreateNewResourceType(RRFreeClient); - if (!ClientType) - return; - EventType = CreateNewResourceType(RRFreeEvents); - if (!EventType) - return; - extEntry = AddExtension (RANDR_NAME, RRNumberEvents, RRNumberErrors, - ProcRRDispatch, SProcRRDispatch, - RRResetProc, StandardMinorOpcode); - if (!extEntry) - return; -#if 0 - RRReqCode = (CARD8) extEntry->base; - RRErrBase = extEntry->errorBase; -#endif - RREventBase = extEntry->eventBase; - EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr) - SRRScreenChangeNotifyEvent; - - return; -} - -int -TellChanged (WindowPtr pWin, pointer value) -{ - RREventPtr *pHead, pRREvent; - ClientPtr client; - xRRScreenChangeNotifyEvent se; - ScreenPtr pScreen = pWin->drawable.pScreen; - rrScrPriv(pScreen); - RRScreenSizePtr pSize; - WindowPtr pRoot = WindowTable[pScreen->myNum]; - - pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, EventType); - if (!pHead) - return WT_WALKCHILDREN; - - se.type = RRScreenChangeNotify + RREventBase; - se.rotation = (CARD8) pScrPriv->rotation; - se.timestamp = pScrPriv->lastSetTime.milliseconds; - 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; -#endif - if (pScrPriv->size >= 0) - { - pSize = &pScrPriv->pSizes[pScrPriv->size]; - se.sizeID = pSize->id; - se.widthInPixels = pSize->width; - se.heightInPixels = pSize->height; - se.widthInMillimeters = pSize->mmWidth; - se.heightInMillimeters = pSize->mmHeight; - } - else - { - /* - * This "shouldn't happen", but a broken DDX can - * forget to set the current configuration on GetInfo - */ - se.sizeID = 0xffff; - se.widthInPixels = 0; - se.heightInPixels = 0; - se.widthInMillimeters = 0; - se.heightInMillimeters = 0; - } - for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) - { - client = pRREvent->client; - if (client == serverClient || client->clientGone) - continue; - se.sequenceNumber = client->sequence; - if(pRREvent->mask & RRScreenChangeNotifyMask) - WriteEventsToClient (client, 1, (xEvent *) &se); - } - return WT_WALKCHILDREN; -} - -Bool -RRGetInfo (ScreenPtr pScreen) -{ - rrScrPriv (pScreen); - int i, j, k, l; - Bool changed; - Rotation rotations; - RRScreenSizePtr pSize; - RRScreenRatePtr pRate; - - for (i = 0; i < pScrPriv->nSizes; i++) - { - pSize = &pScrPriv->pSizes[i]; - pSize->oldReferenced = pSize->referenced; - pSize->referenced = FALSE; - for (k = 0; k < pSize->nRates; k++) - { - pRate = &pSize->pRates[k]; - pRate->oldReferenced = pRate->referenced; - pRate->referenced = FALSE; - } - } - if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations)) - return FALSE; - - changed = FALSE; - - /* - * Check whether anything changed and simultaneously generate - * the protocol id values for the objects - */ - if (rotations != pScrPriv->rotations) - { - pScrPriv->rotations = rotations; - changed = TRUE; - } - - j = 0; - for (i = 0; i < pScrPriv->nSizes; i++) - { - pSize = &pScrPriv->pSizes[i]; - if (pSize->oldReferenced != pSize->referenced) - changed = TRUE; - if (pSize->referenced) - pSize->id = j++; - l = 0; - for (k = 0; k < pSize->nRates; k++) - { - pRate = &pSize->pRates[k]; - if (pRate->oldReferenced != pRate->referenced) - changed = TRUE; - if (pRate->referenced) - l++; - } - pSize->nRatesInUse = l; - } - pScrPriv->nSizesInUse = j; - if (changed) - { - UpdateCurrentTime (); - pScrPriv->lastConfigTime = currentTime; - WalkTree (pScreen, TellChanged, (pointer) pScreen); - } - return TRUE; -} - -void -RRSendConfigNotify (ScreenPtr pScreen) -{ - WindowPtr pWin = WindowTable[pScreen->myNum]; - xEvent event; - - 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); -} - -static int -ProcRRQueryVersion (ClientPtr client) -{ - xRRQueryVersionReply rep; - register int n; - 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; - rep.majorVersion = RANDR_MAJOR; - rep.minorVersion = RANDR_MINOR; - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.majorVersion, n); - swapl(&rep.minorVersion, n); - } - WriteToClient(client, sizeof(xRRQueryVersionReply), (char *)&rep); - return (client->noClientException); -} - - -extern char *ConnectionInfo; - -static int padlength[4] = {0, 3, 2, 1}; - -void -RREditConnectionInfo (ScreenPtr pScreen) -{ - xConnSetup *connSetup; - char *vendor; - xPixmapFormat *formats; - xWindowRoot *root; - xDepth *depth; - xVisualType *visual; - int screen = 0; - int d; - - connSetup = (xConnSetup *) ConnectionInfo; - vendor = (char *) connSetup + sizeof (xConnSetup); - formats = (xPixmapFormat *) ((char *) vendor + - connSetup->nbytesVendor + - padlength[connSetup->nbytesVendor & 3]); - root = (xWindowRoot *) ((char *) formats + - sizeof (xPixmapFormat) * screenInfo.numPixmapFormats); - while (screen != pScreen->myNum) - { - depth = (xDepth *) ((char *) root + - sizeof (xWindowRoot)); - for (d = 0; d < root->nDepths; d++) - { - visual = (xVisualType *) ((char *) depth + - sizeof (xDepth)); - depth = (xDepth *) ((char *) visual + - depth->nVisuals * sizeof (xVisualType)); - } - root = (xWindowRoot *) ((char *) depth); - screen++; - } - root->pixWidth = pScreen->width; - root->pixHeight = pScreen->height; - root->mmWidth = pScreen->mmWidth; - root->mmHeight = pScreen->mmHeight; -} - -static int -ProcRRGetScreenInfo (ClientPtr client) -{ - REQUEST(xRRGetScreenInfoReq); - xRRGetScreenInfoReply rep; - WindowPtr pWin; - int n; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - CARD8 *extra; - unsigned long extraLen; - - REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); - pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, - SecurityReadAccess); - - if (!pWin) - return BadWindow; - - pScreen = pWin->drawable.pScreen; - pScrPriv = rrGetScrPriv(pScreen); - rep.pad = 0; - if (!pScrPriv) - { - 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; - extra = 0; - extraLen = 0; - } - else - { - int i, j; - xScreenSizes *size; - CARD16 *rates; - CARD8 *data8; - Bool has_rate = RRClientKnowsRates (client); - - RRGetInfo (pScreen); - - rep.type = X_Reply; - rep.setOfRotations = pScrPriv->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 = pScrPriv->rotation; - rep.nSizes = pScrPriv->nSizesInUse; - rep.rate = pScrPriv->rate; - rep.nrateEnts = 0; - if (has_rate) - { - for (i = 0; i < pScrPriv->nSizes; i++) - { - RRScreenSizePtr pSize = &pScrPriv->pSizes[i]; - if (pSize->referenced) - { - rep.nrateEnts += (1 + pSize->nRatesInUse); - } - } - } - - if (pScrPriv->size >= 0) - rep.sizeID = pScrPriv->pSizes[pScrPriv->size].id; - else - return BadImplementation; - - extraLen = (rep.nSizes * sizeof (xScreenSizes) + - rep.nrateEnts * sizeof (CARD16)); - - extra = (CARD8 *) xalloc (extraLen); - if (!extra) - return BadAlloc; - /* - * First comes the size information - */ - size = (xScreenSizes *) extra; - rates = (CARD16 *) (size + rep.nSizes); - for (i = 0; i < pScrPriv->nSizes; i++) - { - RRScreenSizePtr pSize = &pScrPriv->pSizes[i]; - if (pSize->referenced) - { - size->widthInPixels = pSize->width; - size->heightInPixels = pSize->height; - size->widthInMillimeters = pSize->mmWidth; - size->heightInMillimeters = pSize->mmHeight; - if (client->swapped) - { - swaps (&size->widthInPixels, n); - swaps (&size->heightInPixels, n); - swaps (&size->widthInMillimeters, n); - swaps (&size->heightInMillimeters, n); - } - size++; - if (has_rate) - { - *rates = pSize->nRatesInUse; - if (client->swapped) - { - swaps (rates, n); - } - rates++; - for (j = 0; j < pSize->nRates; j++) - { - RRScreenRatePtr pRate = &pSize->pRates[j]; - if (pRate->referenced) - { - *rates = pRate->rate; - if (client->swapped) - { - swaps (rates, n); - } - rates++; - } - } - } - } - } - data8 = (CARD8 *) rates; - - if (data8 - (CARD8 *) extra != extraLen) - FatalError ("RRGetScreenInfo bad extra len %ld != %ld\n", - (unsigned long)(data8 - (CARD8 *) extra), extraLen); - rep.length = (extraLen + 3) >> 2; - } - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.timestamp, n); - swaps(&rep.rotation, n); - swaps(&rep.nSizes, n); - swaps(&rep.sizeID, n); - swaps(&rep.rate, n); - swaps(&rep.nrateEnts, n); - } - WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *)&rep); - if (extraLen) - { - WriteToClient (client, extraLen, (char *) extra); - xfree (extra); - } - return (client->noClientException); -} - -static int -ProcRRSetScreenConfig (ClientPtr client) -{ - REQUEST(xRRSetScreenConfigReq); - xRRSetScreenConfigReply rep; - DrawablePtr pDraw; - int n; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - TimeStamp configTime; - TimeStamp time; - RRScreenSizePtr pSize; - int i; - Rotation rotation; - int rate; - short oldWidth, oldHeight; - Bool has_rate; - - UpdateCurrentTime (); - - if (RRClientKnowsRates (client)) - { - REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); - has_rate = TRUE; - } - else - { - REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); - has_rate = FALSE; - } - - SECURITY_VERIFY_DRAWABLE(pDraw, stuff->drawable, client, - SecurityWriteAccess); - - pScreen = pDraw->pScreen; - - pScrPriv = rrGetScrPriv(pScreen); - - time = ClientTimeToServerTime(stuff->timestamp); - configTime = ClientTimeToServerTime(stuff->configTimestamp); - - oldWidth = pScreen->width; - oldHeight = pScreen->height; - - if (!pScrPriv) - { - time = currentTime; - rep.status = RRSetConfigFailed; - goto sendReply; - } - if (!RRGetInfo (pScreen)) - return BadAlloc; - - /* - * if the client's config timestamp is not the same as the last config - * timestamp, then the config information isn't up-to-date and - * can't even be validated - */ - if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0) - { - rep.status = RRSetConfigInvalidConfigTime; - goto sendReply; - } - - /* - * Search for the requested size - */ - pSize = 0; - for (i = 0; i < pScrPriv->nSizes; i++) - { - pSize = &pScrPriv->pSizes[i]; - if (pSize->referenced && pSize->id == stuff->sizeID) - { - break; - } - } - if (i == pScrPriv->nSizes) - { - /* - * Invalid size ID - */ - client->errorValue = stuff->sizeID; - return BadValue; - } - - /* - * Validate requested rotation - */ - rotation = (Rotation) stuff->rotation; - - /* test the rotation bits only! */ - switch (rotation & 0xf) { - case RR_Rotate_0: - case RR_Rotate_90: - case RR_Rotate_180: - case RR_Rotate_270: - break; - default: - /* - * Invalid rotation - */ - client->errorValue = stuff->rotation; - return BadValue; - } - - if ((~pScrPriv->rotations) & rotation) - { - /* - * requested rotation or reflection not supported by screen - */ - client->errorValue = stuff->rotation; - return BadMatch; - } - - /* - * Validate requested refresh - */ - if (has_rate) - rate = (int) stuff->rate; - else - rate = 0; - - if (rate) - { - for (i = 0; i < pSize->nRates; i++) - { - RRScreenRatePtr pRate = &pSize->pRates[i]; - if (pRate->referenced && pRate->rate == rate) - break; - } - if (i == pSize->nRates) - { - /* - * Invalid rate - */ - client->errorValue = rate; - return BadValue; - } - } - - /* - * 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; - } - - /* - * call out to ddx routine to effect the change - */ - if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate, - pSize)) - { - /* - * unknown DDX failure, report to client - */ - rep.status = RRSetConfigFailed; - goto sendReply; - } - - /* - * set current extension configuration pointers - */ - RRSetCurrentConfig (pScreen, rotation, rate, pSize); - - /* - * Deliver ScreenChangeNotify events whenever - * the configuration is updated - */ - WalkTree (pScreen, TellChanged, (pointer) pScreen); - - /* - * Deliver ConfigureNotify events when root changes - * pixel size - */ - if (oldWidth != pScreen->width || oldHeight != pScreen->height) - RRSendConfigNotify (pScreen); - RREditConnectionInfo (pScreen); - - /* - * Fix pointer bounds and location - */ - ScreenRestructured (pScreen); - pScrPriv->lastSetTime = time; - - /* - * Report Success - */ - rep.status = RRSetConfigSuccess; - -sendReply: - - rep.type = X_Reply; - /* rep.status has already been filled in */ - rep.length = 0; - rep.sequenceNumber = client->sequence; - - rep.newTimestamp = pScrPriv->lastSetTime.milliseconds; - rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds; - rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id; - - if (client->swapped) - { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.newTimestamp, n); - swapl(&rep.newConfigTimestamp, n); - swapl(&rep.root, n); - } - WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *)&rep); - - return (client->noClientException); -} - -int -RRSetScreenConfig (ScreenPtr pScreen, - Rotation rotation, - int rate, - RRScreenSizePtr pSize) -{ - rrScrPrivPtr pScrPriv; - int i; - short oldWidth, oldHeight; - - pScrPriv = rrGetScrPriv(pScreen); - - oldWidth = pScreen->width; - oldHeight = pScreen->height; - - if (!RRGetInfo (pScreen)) - return BadAlloc; - - /* - * Validate requested rotation - */ - - /* test the rotation bits only! */ - switch (rotation & 0xf) { - case RR_Rotate_0: - case RR_Rotate_90: - case RR_Rotate_180: - case RR_Rotate_270: - break; - default: - /* - * Invalid rotation - */ - return BadValue; - } - - if ((~pScrPriv->rotations) & rotation) - { - /* - * requested rotation or reflection not supported by screen - */ - return BadMatch; - } - - /* - * Validate requested refresh - */ - if (rate) - { - for (i = 0; i < pSize->nRates; i++) - { - RRScreenRatePtr pRate = &pSize->pRates[i]; - if (pRate->referenced && pRate->rate == rate) - break; - } - if (i == pSize->nRates) - { - /* - * Invalid rate - */ - return BadValue; - } - } - - /* - * call out to ddx routine to effect the change - */ - if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate, - pSize)) - { - /* - * unknown DDX failure, report to client - */ - return BadImplementation; - } - - /* - * set current extension configuration pointers - */ - RRSetCurrentConfig (pScreen, rotation, rate, pSize); - - /* - * Deliver ScreenChangeNotify events whenever - * the configuration is updated - */ - WalkTree (pScreen, TellChanged, (pointer) pScreen); - - /* - * Deliver ConfigureNotify events when root changes - * pixel size - */ - if (oldWidth != pScreen->width || oldHeight != pScreen->height) - RRSendConfigNotify (pScreen); - RREditConnectionInfo (pScreen); - - /* - * Fix pointer bounds and location - */ - ScreenRestructured (pScreen); - - return Success; -} - -static int -ProcRRSelectInput (ClientPtr client) -{ - REQUEST(xRRSelectInputReq); - rrClientPriv(client); - RRTimesPtr pTimes; - WindowPtr pWin; - RREventPtr pRREvent, pNewRREvent, *pHead; - XID clientResource; - - REQUEST_SIZE_MATCH(xRRSelectInputReq); - pWin = SecurityLookupWindow (stuff->window, client, SecurityWriteAccess); - if (!pWin) - return BadWindow; - pHead = (RREventPtr *)SecurityLookupIDByType(client, - pWin->drawable.id, EventType, - SecurityWriteAccess); - - if (stuff->enable & (RRScreenChangeNotifyMask)) - { - ScreenPtr pScreen = pWin->drawable.pScreen; - rrScrPriv (pScreen); - - if (pHead) - { - /* check for existing entry. */ - for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) - if (pRREvent->client == client) - return Success; - } - - /* build the entry */ - pNewRREvent = (RREventPtr) xalloc (sizeof (RREventRec)); - if (!pNewRREvent) - return BadAlloc; - pNewRREvent->next = 0; - pNewRREvent->client = client; - pNewRREvent->window = pWin; - pNewRREvent->mask = stuff->enable; - /* - * add a resource that will be deleted when - * the client goes away - */ - clientResource = FakeClientID (client->index); - pNewRREvent->clientResource = clientResource; - if (!AddResource (clientResource, ClientType, (pointer)pNewRREvent)) - return BadAlloc; - /* - * create a resource to contain a pointer to the list - * of clients selecting input. This must be indirect as - * the list may be arbitrarily rearranged which cannot be - * done through the resource database. - */ - if (!pHead) - { - pHead = (RREventPtr *) xalloc (sizeof (RREventPtr)); - if (!pHead || - !AddResource (pWin->drawable.id, EventType, (pointer)pHead)) - { - FreeResource (clientResource, RT_NONE); - return BadAlloc; - } - *pHead = 0; - } - pNewRREvent->next = *pHead; - *pHead = pNewRREvent; - /* - * Now see if the client needs an event - */ - if (pScrPriv) - { - pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum]; - if (CompareTimeStamps (pTimes->setTime, - pScrPriv->lastSetTime) != 0 || - CompareTimeStamps (pTimes->configTime, - pScrPriv->lastConfigTime) != 0) - { - TellChanged (pWin, (pointer) pScreen); - } - } - } - else if (stuff->enable == xFalse) - { - /* delete the interest */ - if (pHead) { - pNewRREvent = 0; - for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) { - if (pRREvent->client == client) - break; - pNewRREvent = pRREvent; - } - if (pRREvent) { - FreeResource (pRREvent->clientResource, ClientType); - if (pNewRREvent) - pNewRREvent->next = pRREvent->next; - else - *pHead = pRREvent->next; - xfree (pRREvent); - } - } - } - else - { - client->errorValue = stuff->enable; - return BadValue; - } - return Success; -} - - -static int -ProcRRDispatch (ClientPtr client) -{ - REQUEST(xReq); - switch (stuff->data) - { - case X_RRQueryVersion: - return ProcRRQueryVersion(client); - case X_RRSetScreenConfig: - return ProcRRSetScreenConfig(client); - case X_RRSelectInput: - return ProcRRSelectInput(client); - case X_RRGetScreenInfo: - return ProcRRGetScreenInfo(client); - default: - return BadRequest; - } -} - -static int -SProcRRQueryVersion (ClientPtr client) -{ - register int n; - REQUEST(xRRQueryVersionReq); - - swaps(&stuff->length, n); - swapl(&stuff->majorVersion, n); - swapl(&stuff->minorVersion, n); - return ProcRRQueryVersion(client); -} - -static int -SProcRRGetScreenInfo (ClientPtr client) -{ - register int n; - REQUEST(xRRGetScreenInfoReq); - - swaps(&stuff->length, n); - swapl(&stuff->window, n); - return ProcRRGetScreenInfo(client); -} - -static int -SProcRRSetScreenConfig (ClientPtr client) -{ - register int n; - REQUEST(xRRSetScreenConfigReq); - - if (RRClientKnowsRates (client)) - { - REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); - swaps (&stuff->rate, n); - } - else - { - REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); - } - - swaps(&stuff->length, n); - swapl(&stuff->drawable, n); - swapl(&stuff->timestamp, n); - swaps(&stuff->sizeID, n); - swaps(&stuff->rotation, n); - return ProcRRSetScreenConfig(client); -} - -static int -SProcRRSelectInput (ClientPtr client) -{ - register int n; - REQUEST(xRRSelectInputReq); - - swaps(&stuff->length, n); - swapl(&stuff->window, n); - return ProcRRSelectInput(client); -} - - -static int -SProcRRDispatch (ClientPtr client) -{ - REQUEST(xReq); - switch (stuff->data) - { - case X_RRQueryVersion: - return SProcRRQueryVersion(client); - case X_RRSetScreenConfig: - return SProcRRSetScreenConfig(client); - case X_RRSelectInput: - return SProcRRSelectInput(client); - case X_RRGetScreenInfo: - return SProcRRGetScreenInfo(client); - default: - return BadRequest; - } -} - - -static Bool -RRScreenSizeMatches (RRScreenSizePtr a, - RRScreenSizePtr b) -{ - if (a->width != b->width) - return FALSE; - if (a->height != b->height) - return FALSE; - if (a->mmWidth != b->mmWidth) - return FALSE; - if (a->mmHeight != b->mmHeight) - return FALSE; - return TRUE; -} - -RRScreenSizePtr -RRRegisterSize (ScreenPtr pScreen, - short width, - short height, - short mmWidth, - short mmHeight) -{ - rrScrPriv (pScreen); - int i; - RRScreenSize tmp; - RRScreenSizePtr pNew; - - if (!pScrPriv) - return 0; - - /* - * FIXME: The compiler reports that field - * id is used uninitialized here. - */ - - tmp.id = 0; - - tmp.width = width; - tmp.height= height; - tmp.mmWidth = mmWidth; - tmp.mmHeight = mmHeight; - tmp.pRates = 0; - tmp.nRates = 0; - tmp.nRatesInUse = 0; - tmp.referenced = TRUE; - tmp.oldReferenced = FALSE; - for (i = 0; i < pScrPriv->nSizes; i++) - if (RRScreenSizeMatches (&tmp, &pScrPriv->pSizes[i])) - { - pScrPriv->pSizes[i].referenced = TRUE; - return &pScrPriv->pSizes[i]; - } - pNew = xrealloc (pScrPriv->pSizes, - (pScrPriv->nSizes + 1) * sizeof (RRScreenSize)); - if (!pNew) - return 0; - pNew[pScrPriv->nSizes++] = tmp; - pScrPriv->pSizes = pNew; - return &pNew[pScrPriv->nSizes-1]; -} - -Bool RRRegisterRate (ScreenPtr pScreen, - RRScreenSizePtr pSize, - int rate) -{ - rrScrPriv(pScreen); - int i; - RRScreenRatePtr pNew, pRate; - - if (!pScrPriv) - return FALSE; - - for (i = 0; i < pSize->nRates; i++) - { - pRate = &pSize->pRates[i]; - if (pRate->rate == rate) - { - pRate->referenced = TRUE; - return TRUE; - } - } - - pNew = xrealloc (pSize->pRates, - (pSize->nRates + 1) * sizeof (RRScreenRate)); - if (!pNew) - return FALSE; - pRate = &pNew[pSize->nRates++]; - pRate->rate = rate; - pRate->referenced = TRUE; - pRate->oldReferenced = FALSE; - pSize->pRates = pNew; - return TRUE; -} - -void -RRSetCurrentConfig (ScreenPtr pScreen, - Rotation rotation, - int rate, - RRScreenSizePtr pSize) -{ - rrScrPriv (pScreen); - - if (!pScrPriv) - return; - - pScrPriv->rotation = rotation; - pScrPriv->size = pSize - pScrPriv->pSizes; - pScrPriv->rate = rate; -} - diff --git a/programs/Xserver/randr/Imakefile b/programs/Xserver/randr.X.original/Imakefile similarity index 100% copy from programs/Xserver/randr/Imakefile copy to programs/Xserver/randr.X.original/Imakefile diff --git a/programs/Xserver/randr/mirandr.c b/programs/Xserver/randr.X.original/mirandr.c similarity index 100% copy from programs/Xserver/randr/mirandr.c copy to programs/Xserver/randr.X.original/mirandr.c diff --git a/programs/Xserver/hw/nxagent/X/NXrandr.c.X.original b/programs/Xserver/randr.X.original/randr.c similarity index 100% rename from programs/Xserver/hw/nxagent/X/NXrandr.c.X.original rename to programs/Xserver/randr.X.original/randr.c diff --git a/programs/Xserver/randr/randrstr.h b/programs/Xserver/randr.X.original/randrstr.h similarity index 100% copy from programs/Xserver/randr/randrstr.h copy to programs/Xserver/randr.X.original/randrstr.h diff --git a/programs/Xserver/randr/Imakefile b/programs/Xserver/randr/Imakefile index 73b0dfb..2eff07f 100644 --- a/programs/Xserver/randr/Imakefile +++ b/programs/Xserver/randr/Imakefile @@ -1,15 +1,33 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */ +/* */ +/* NX-X11, NX protocol compression and NX extensions to this software */ +/* are copyright of NoMachine. Redistribution and use of the present */ +/* software is allowed according to terms specified in the file LICENSE */ +/* which comes in the source distribution. */ +/* */ +/* Check http://www.nomachine.com/licensing.html for applicability. */ +/* */ +/* NX and NoMachine are trademarks of Medialogic S.p.A. */ +/* */ +/* All rights reserved. */ +/* */ +/**************************************************************************/ XCOMM $XFree86: xc/programs/Xserver/randr/Imakefile,v 1.1 2001/05/23 03:29:44 keithp Exp $ #include <Server.tmpl> - SRCS = randr.c mirandr.c + SRCS = mirandr.c randr.c rrcrtc.c rrdispatch.c rrinfo.c rrmode.c rroutput.c rrpointer.c rrproperty.c rrscreen.c rrsdispatch.c rrxinerama.c - OBJS = randr.o mirandr.o + OBJS = mirandr.o randr.o rrcrtc.o rrdispatch.o rrinfo.o rrmode.o rroutput.o rrpointer.o rrproperty.o rrscreen.o rrsdispatch.o rrxinerama.o INCLUDES = -I../include -I../mi -I../../../include/fonts \ -I../fb -I../hw/kdrive -I$(EXTINCSRC) -I$(XINCLUDESRC) \ -I$(FONTINCSRC) -I../render LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln + DEFINES = -DNXAGENT_SERVER + NormalLibraryTarget(randr,$(OBJS)) NormalLibraryObjectRule() LintLibraryTarget(randr,$(SRCS)) diff --git a/programs/Xserver/randr/Imakefile.NX.original b/programs/Xserver/randr/Imakefile.NX.original new file mode 100644 index 0000000..2eff07f --- /dev/null +++ b/programs/Xserver/randr/Imakefile.NX.original @@ -0,0 +1,36 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */ +/* */ +/* NX-X11, NX protocol compression and NX extensions to this software */ +/* are copyright of NoMachine. Redistribution and use of the present */ +/* software is allowed according to terms specified in the file LICENSE */ +/* which comes in the source distribution. */ +/* */ +/* Check http://www.nomachine.com/licensing.html for applicability. */ +/* */ +/* NX and NoMachine are trademarks of Medialogic S.p.A. */ +/* */ +/* All rights reserved. */ +/* */ +/**************************************************************************/ +XCOMM $XFree86: xc/programs/Xserver/randr/Imakefile,v 1.1 2001/05/23 03:29:44 keithp Exp $ +#include <Server.tmpl> + + SRCS = mirandr.c randr.c rrcrtc.c rrdispatch.c rrinfo.c rrmode.c rroutput.c rrpointer.c rrproperty.c rrscreen.c rrsdispatch.c rrxinerama.c + + OBJS = mirandr.o randr.o rrcrtc.o rrdispatch.o rrinfo.o rrmode.o rroutput.o rrpointer.o rrproperty.o rrscreen.o rrsdispatch.o rrxinerama.o + + INCLUDES = -I../include -I../mi -I../../../include/fonts \ + -I../fb -I../hw/kdrive -I$(EXTINCSRC) -I$(XINCLUDESRC) \ + -I$(FONTINCSRC) -I../render + LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln + + DEFINES = -DNXAGENT_SERVER + +NormalLibraryTarget(randr,$(OBJS)) +NormalLibraryObjectRule() +LintLibraryTarget(randr,$(SRCS)) +NormalLintTarget($(SRCS)) + +DependTarget() diff --git a/CHANGELOG.X.original b/programs/Xserver/randr/Imakefile.X.original similarity index 100% copy from CHANGELOG.X.original copy to programs/Xserver/randr/Imakefile.X.original diff --git a/programs/Xserver/randr/Makefile.am b/programs/Xserver/randr/Makefile.am new file mode 100644 index 0000000..20b0f72 --- /dev/null +++ b/programs/Xserver/randr/Makefile.am @@ -0,0 +1,28 @@ +noinst_LTLIBRARIES = librandr.la + +AM_CFLAGS = $(DIX_CFLAGS) + +XINERAMA_SRCS = rrxinerama.c + +if XORG +sdk_HEADERS = randrstr.h +endif + +librandr_la_SOURCES = \ + mirandr.c \ + randr.c \ + randrstr.h \ + rrcrtc.c \ + rrdispatch.c \ + rrinfo.c \ + rrmode.c \ + rroutput.c \ + rrpointer.c \ + rrproperty.c \ + rrscreen.c \ + rrsdispatch.c + +if XINERAMA +librandr_la_SOURCES += ${XINERAMA_SRCS} +endif + diff --git a/programs/Xserver/randr/Makefile.in b/programs/Xserver/randr/Makefile.in new file mode 100644 index 0000000..447f6cb --- /dev/null +++ b/programs/Xserver/randr/Makefile.in @@ -0,0 +1,698 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@XINERAMA_TRUE@am__append_1 = ${XINERAMA_SRCS} +subdir = randr +DIST_COMMON = $(am__sdk_HEADERS_DIST) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/include/do-not-use-config.h \ + $(top_builddir)/include/xorg-server.h \ + $(top_builddir)/include/dix-config.h \ + $(top_builddir)/include/xgl-config.h \ + $(top_builddir)/include/xorg-config.h \ + $(top_builddir)/include/xkb-config.h \ + $(top_builddir)/include/xwin-config.h \ + $(top_builddir)/include/kdrive-config.h +CONFIG_CLEAN_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +librandr_la_LIBADD = +am__librandr_la_SOURCES_DIST = mirandr.c randr.c randrstr.h rrcrtc.c \ + rrdispatch.c rrinfo.c rrmode.c rroutput.c rrpointer.c \ + rrproperty.c rrscreen.c rrsdispatch.c rrxinerama.c +am__objects_1 = rrxinerama.lo +@XINERAMA_TRUE@am__objects_2 = $(am__objects_1) +am_librandr_la_OBJECTS = mirandr.lo randr.lo rrcrtc.lo rrdispatch.lo \ + rrinfo.lo rrmode.lo rroutput.lo rrpointer.lo rrproperty.lo \ + rrscreen.lo rrsdispatch.lo $(am__objects_2) +librandr_la_OBJECTS = $(am_librandr_la_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(librandr_la_SOURCES) +DIST_SOURCES = $(am__librandr_la_SOURCES_DIST) +am__sdk_HEADERS_DIST = randrstr.h +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(sdkdir)" +sdkHEADERS_INSTALL = $(INSTALL_HEADER) +HEADERS = $(sdk_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ADMIN_MAN_DIR = @ADMIN_MAN_DIR@ +ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +APPDEFAULTDIR = @APPDEFAULTDIR@ +APPLE_APPLICATIONS_DIR = @APPLE_APPLICATIONS_DIR@ +APP_MAN_DIR = @APP_MAN_DIR@ +APP_MAN_SUFFIX = @APP_MAN_SUFFIX@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BASE_FONT_PATH = @BASE_FONT_PATH@ +BUILD_DATE = @BUILD_DATE@ +BUILD_TIME = @BUILD_TIME@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +COMPILEDDEFAULTFONTPATH = @COMPILEDDEFAULTFONTPATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DARWIN_LIBS = @DARWIN_LIBS@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DEFAULT_LIBRARY_PATH = @DEFAULT_LIBRARY_PATH@ +DEFAULT_LOGPREFIX = @DEFAULT_LOGPREFIX@ +DEFAULT_MODULE_PATH = @DEFAULT_MODULE_PATH@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DGA_CFLAGS = @DGA_CFLAGS@ +DGA_LIBS = @DGA_LIBS@ +DIX_CFLAGS = @DIX_CFLAGS@ +DLLTOOL = @DLLTOOL@ +DMXEXAMPLES_DEP_CFLAGS = @DMXEXAMPLES_DEP_CFLAGS@ +DMXEXAMPLES_DEP_LIBS = @DMXEXAMPLES_DEP_LIBS@ +DMXMODULES_CFLAGS = @DMXMODULES_CFLAGS@ +DMXMODULES_LIBS = @DMXMODULES_LIBS@ +DMXXIEXAMPLES_DEP_CFLAGS = @DMXXIEXAMPLES_DEP_CFLAGS@ +DMXXIEXAMPLES_DEP_LIBS = @DMXXIEXAMPLES_DEP_LIBS@ +DMXXMUEXAMPLES_DEP_CFLAGS = @DMXXMUEXAMPLES_DEP_CFLAGS@ +DMXXMUEXAMPLES_DEP_LIBS = @DMXXMUEXAMPLES_DEP_LIBS@ +DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@ +DRI2PROTO_LIBS = @DRI2PROTO_LIBS@ +DRIPROTO_CFLAGS = @DRIPROTO_CFLAGS@ +DRIPROTO_LIBS = @DRIPROTO_LIBS@ +DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ +DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ +DRI_DRIVER_PATH = @DRI_DRIVER_PATH@ +DSYMUTIL = @DSYMUTIL@ +DTRACE = @DTRACE@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +FILE_MAN_DIR = @FILE_MAN_DIR@ +FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@ +FREETYPE_CFLAGS = @FREETYPE_CFLAGS@ +FREETYPE_LIBS = @FREETYPE_LIBS@ +GLX_ARCH_DEFINES = @GLX_ARCH_DEFINES@ +GLX_DEFINES = @GLX_DEFINES@ +GL_CFLAGS = @GL_CFLAGS@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +HAL_CFLAGS = @HAL_CFLAGS@ +HAL_LIBS = @HAL_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KDRIVE_CFLAGS = @KDRIVE_CFLAGS@ +KDRIVE_INCS = @KDRIVE_INCS@ +KDRIVE_LIBS = @KDRIVE_LIBS@ +KDRIVE_LOCAL_LIBS = @KDRIVE_LOCAL_LIBS@ +KDRIVE_PURE_INCS = @KDRIVE_PURE_INCS@ +KDRIVE_PURE_LIBS = @KDRIVE_PURE_LIBS@ +LAUNCHD = @LAUNCHD@ +LDFLAGS = @LDFLAGS@ +LD_EXPORT_SYMBOLS_FLAG = @LD_EXPORT_SYMBOLS_FLAG@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBDRM_CFLAGS = @LIBDRM_CFLAGS@ +LIBDRM_LIBS = @LIBDRM_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIB_MAN_DIR = @LIB_MAN_DIR@ +LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ +LINUXDOC = @LINUXDOC@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MAKE_HTML = @MAKE_HTML@ +MAKE_PDF = @MAKE_PDF@ +MAKE_PS = @MAKE_PS@ +MAKE_TEXT = @MAKE_TEXT@ +MESA_SOURCE = @MESA_SOURCE@ +MISC_MAN_DIR = @MISC_MAN_DIR@ +MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@ +MKDIR_P = @MKDIR_P@ +MKFONTDIR = @MKFONTDIR@ +MKFONTSCALE = @MKFONTSCALE@ +NMEDIT = @NMEDIT@ +OBJC = @OBJC@ +OBJCCLD = @OBJCCLD@ +OBJCDEPMODE = @OBJCDEPMODE@ +OBJCFLAGS = @OBJCFLAGS@ +OBJCLINK = @OBJCLINK@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PCIACCESS_CFLAGS = @PCIACCESS_CFLAGS@ +PCIACCESS_LIBS = @PCIACCESS_LIBS@ +PCI_TXT_IDS_PATH = @PCI_TXT_IDS_PATH@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PROJECTROOT = @PROJECTROOT@ +PS2PDF = @PS2PDF@ +RANLIB = @RANLIB@ +RAWCPP = @RAWCPP@ +RAWCPPFLAGS = @RAWCPPFLAGS@ +SED = @SED@ +SERVER_MISC_CONFIG_PATH = @SERVER_MISC_CONFIG_PATH@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOLARIS_ASM_CFLAGS = @SOLARIS_ASM_CFLAGS@ +SOLARIS_INOUT_ARCH = @SOLARIS_INOUT_ARCH@ +STRIP = @STRIP@ +TSLIB_CFLAGS = @TSLIB_CFLAGS@ +TSLIB_LIBS = @TSLIB_LIBS@ +UTILS_SYS_LIBS = @UTILS_SYS_LIBS@ +VENDOR_MAN_VERSION = @VENDOR_MAN_VERSION@ +VENDOR_NAME = @VENDOR_NAME@ +VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@ +VENDOR_RELEASE = @VENDOR_RELEASE@ +VERSION = @VERSION@ +X11APP_ARCHS = @X11APP_ARCHS@ +X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@ +X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@ +XDMCP_CFLAGS = @XDMCP_CFLAGS@ +XDMCP_LIBS = @XDMCP_LIBS@ +XDMXCONFIG_DEP_CFLAGS = @XDMXCONFIG_DEP_CFLAGS@ +XDMXCONFIG_DEP_LIBS = @XDMXCONFIG_DEP_LIBS@ +XDMX_CFLAGS = @XDMX_CFLAGS@ +XDMX_LIBS = @XDMX_LIBS@ +XDMX_SYS_LIBS = @XDMX_SYS_LIBS@ +XEGLMODULES_CFLAGS = @XEGLMODULES_CFLAGS@ +XEGL_LIBS = @XEGL_LIBS@ +XEGL_SYS_LIBS = @XEGL_SYS_LIBS@ +XEPHYR_CFLAGS = @XEPHYR_CFLAGS@ +XEPHYR_DRI_LIBS = @XEPHYR_DRI_LIBS@ +XEPHYR_INCS = @XEPHYR_INCS@ +XEPHYR_LIBS = @XEPHYR_LIBS@ +XF86CONFIGFILE = @XF86CONFIGFILE@ +XF86MISC_CFLAGS = @XF86MISC_CFLAGS@ +XF86MISC_LIBS = @XF86MISC_LIBS@ +XF86VIDMODE_CFLAGS = @XF86VIDMODE_CFLAGS@ +XF86VIDMODE_LIBS = @XF86VIDMODE_LIBS@ +XGLMODULES_CFLAGS = @XGLMODULES_CFLAGS@ +XGLMODULES_LIBS = @XGLMODULES_LIBS@ +XGLXMODULES_CFLAGS = @XGLXMODULES_CFLAGS@ +XGLXMODULES_LIBS = @XGLXMODULES_LIBS@ +XGLX_LIBS = @XGLX_LIBS@ +XGLX_SYS_LIBS = @XGLX_SYS_LIBS@ +XGL_LIBS = @XGL_LIBS@ +XGL_MODULE_PATH = @XGL_MODULE_PATH@ +XGL_SYS_LIBS = @XGL_SYS_LIBS@ +XKB_BASE_DIRECTORY = @XKB_BASE_DIRECTORY@ +XKB_BIN_DIRECTORY = @XKB_BIN_DIRECTORY@ +XKB_COMPILED_DIR = @XKB_COMPILED_DIR@ +XKM_OUTPUT_DIR = @XKM_OUTPUT_DIR@ +XLIB_CFLAGS = @XLIB_CFLAGS@ +XLIB_LIBS = @XLIB_LIBS@ +XNESTMODULES_CFLAGS = @XNESTMODULES_CFLAGS@ +XNESTMODULES_LIBS = @XNESTMODULES_LIBS@ +XNEST_LIBS = @XNEST_LIBS@ +XNEST_SYS_LIBS = @XNEST_SYS_LIBS@ +XORGCFG_DEP_CFLAGS = @XORGCFG_DEP_CFLAGS@ +XORGCFG_DEP_LIBS = @XORGCFG_DEP_LIBS@ +XORGCONFIG_DEP_CFLAGS = @XORGCONFIG_DEP_CFLAGS@ +XORGCONFIG_DEP_LIBS = @XORGCONFIG_DEP_LIBS@ +XORG_CFLAGS = @XORG_CFLAGS@ +XORG_INCS = @XORG_INCS@ +XORG_LIBS = @XORG_LIBS@ +XORG_MODULES_CFLAGS = @XORG_MODULES_CFLAGS@ +XORG_MODULES_LIBS = @XORG_MODULES_LIBS@ +XORG_OS = @XORG_OS@ +XORG_OS_SUBDIR = @XORG_OS_SUBDIR@ +XORG_SYS_LIBS = @XORG_SYS_LIBS@ +XPRINTMODULES_CFLAGS = @XPRINTMODULES_CFLAGS@ +XPRINTMODULES_LIBS = @XPRINTMODULES_LIBS@ +XPRINTPROTO_CFLAGS = @XPRINTPROTO_CFLAGS@ +XPRINTPROTO_LIBS = @XPRINTPROTO_LIBS@ +XPRINT_CFLAGS = @XPRINT_CFLAGS@ +XPRINT_LIBS = @XPRINT_LIBS@ +XPRINT_SYS_LIBS = @XPRINT_SYS_LIBS@ +XRESEXAMPLES_DEP_CFLAGS = @XRESEXAMPLES_DEP_CFLAGS@ +XRESEXAMPLES_DEP_LIBS = @XRESEXAMPLES_DEP_LIBS@ +XSDL_INCS = @XSDL_INCS@ +XSDL_LIBS = @XSDL_LIBS@ +XSERVERCFLAGS_CFLAGS = @XSERVERCFLAGS_CFLAGS@ +XSERVERCFLAGS_LIBS = @XSERVERCFLAGS_LIBS@ +XSERVERLIBS_CFLAGS = @XSERVERLIBS_CFLAGS@ +XSERVERLIBS_LIBS = @XSERVERLIBS_LIBS@ +XSERVER_LIBS = @XSERVER_LIBS@ +XSERVER_SYS_LIBS = @XSERVER_SYS_LIBS@ +XTSTEXAMPLES_DEP_CFLAGS = @XTSTEXAMPLES_DEP_CFLAGS@ +XTSTEXAMPLES_DEP_LIBS = @XTSTEXAMPLES_DEP_LIBS@ +XVFB_LIBS = @XVFB_LIBS@ +XVFB_SYS_LIBS = @XVFB_SYS_LIBS@ +XWINMODULES_CFLAGS = @XWINMODULES_CFLAGS@ +XWINMODULES_LIBS = @XWINMODULES_LIBS@ +XWIN_LIBS = @XWIN_LIBS@ +XWIN_SERVER_NAME = @XWIN_SERVER_NAME@ +XWIN_SYS_LIBS = @XWIN_SYS_LIBS@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +__XCONFIGFILE__ = @__XCONFIGFILE__@ +abi_ansic = @abi_ansic@ +abi_extension = @abi_extension@ +abi_font = @abi_font@ +abi_videodrv = @abi_videodrv@ +abi_xinput = @abi_xinput@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +driverdir = @driverdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +extdir = @extdir@ +ft_config = @ft_config@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +launchagentsdir = @launchagentsdir@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +logdir = @logdir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moduledir = @moduledir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sdkdir = @sdkdir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +xglmoduledir = @xglmoduledir@ +xpconfigdir = @xpconfigdir@ +noinst_LTLIBRARIES = librandr.la +AM_CFLAGS = $(DIX_CFLAGS) +XINERAMA_SRCS = rrxinerama.c +@XORG_TRUE@sdk_HEADERS = randrstr.h +librandr_la_SOURCES = mirandr.c randr.c randrstr.h rrcrtc.c \ + rrdispatch.c rrinfo.c rrmode.c rroutput.c rrpointer.c \ + rrproperty.c rrscreen.c rrsdispatch.c $(am__append_1) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign randr/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign randr/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +librandr.la: $(librandr_la_OBJECTS) $(librandr_la_DEPENDENCIES) + $(LINK) $(librandr_la_OBJECTS) $(librandr_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mirandr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/randr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrcrtc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrdispatch.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrinfo.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrmode.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rroutput.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrpointer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrproperty.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrscreen.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrsdispatch.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrxinerama.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-sdkHEADERS: $(sdk_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(sdkdir)" || $(MKDIR_P) "$(DESTDIR)$(sdkdir)" + @list='$(sdk_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(sdkHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(sdkdir)/$$f'"; \ + $(sdkHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(sdkdir)/$$f"; \ + done + +uninstall-sdkHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(sdk_HEADERS)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(sdkdir)/$$f'"; \ + rm -f "$(DESTDIR)$(sdkdir)/$$f"; \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(sdkdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-sdkHEADERS + +install-dvi: install-dvi-am + +install-exec-am: + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-sdkHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-sdkHEADERS install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-sdkHEADERS + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/programs/Xserver/randr/mirandr.c b/programs/Xserver/randr/mirandr.c index b1e19a7..3c4991e 100644 --- a/programs/Xserver/randr/mirandr.c +++ b/programs/Xserver/randr/mirandr.c @@ -1,76 +1,42 @@ /* - * $XFree86: xc/programs/Xserver/randr/mirandr.c,v 1.5 2001/06/04 09:45:40 keithp Exp $ - * - * Copyright © 2000, Compaq Computer Corporation, - * Copyright © 2002, Hewlett Packard, Inc. + * Copyright © 2000 Compaq Computer Corporation + * Copyright © 2002 Hewlett-Packard Company + * Copyright © 2006 Intel Corporation * * 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 Compaq or HP not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. HP makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. + * 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. * - * HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL HP - * 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. + * 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. * - * Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc. + * Author: Jim Gettys, Hewlett-Packard Company, Inc. + * Keith Packard, Intel Corporation */ - #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> #endif #include "scrnintstr.h" #include "mi.h" -#include <X11/extensions/randr.h> #include "randrstr.h" #include <stdio.h> -/* - * This function assumes that only a single depth can be - * displayed at a time, but that all visuals of that depth - * can be displayed simultaneously. It further assumes that - * only a single size is available. Hardware providing - * additional capabilties should use different code. - * XXX what to do here.... - */ - Bool miRRGetInfo (ScreenPtr pScreen, Rotation *rotations) { - int i; - Bool setConfig = FALSE; - - *rotations = RR_Rotate_0; - for (i = 0; i < pScreen->numDepths; i++) - { - if (pScreen->allowedDepths[i].numVids) - { - RRScreenSizePtr pSize; - - pSize = RRRegisterSize (pScreen, - pScreen->width, - pScreen->height, - pScreen->mmWidth, - pScreen->mmHeight); - if (!pSize) - return FALSE; - if (!setConfig) - { - RRSetCurrentConfig (pScreen, RR_Rotate_0, 0, pSize); - setConfig = TRUE; - } - } - } return TRUE; } @@ -79,24 +45,110 @@ miRRGetInfo (ScreenPtr pScreen, Rotation *rotations) * different here */ Bool -miRRSetConfig (ScreenPtr pScreen, - Rotation rotation, - int rate, - RRScreenSizePtr pSize) +miRRCrtcSet (ScreenPtr pScreen, + RRCrtcPtr crtc, + RRModePtr mode, + int x, + int y, + Rotation rotation, + int numOutput, + RROutputPtr *outputs) { return TRUE; } +static Bool +miRRCrtcSetGamma (ScreenPtr pScreen, + RRCrtcPtr crtc) +{ + return TRUE; +} + +Bool +miRROutputSetProperty (ScreenPtr pScreen, + RROutputPtr output, + Atom property, + RRPropertyValuePtr value) +{ + return TRUE; +} + +Bool +miRROutputValidateMode (ScreenPtr pScreen, + RROutputPtr output, + RRModePtr mode) +{ + return FALSE; +} + +void +miRRModeDestroy (ScreenPtr pScreen, + RRModePtr mode) +{ +} + +/* + * This function assumes that only a single depth can be + * displayed at a time, but that all visuals of that depth + * can be displayed simultaneously. It further assumes that + * only a single size is available. Hardware providing + * additional capabilties should use different code. + * XXX what to do here.... + */ Bool miRandRInit (ScreenPtr pScreen) { - rrScrPrivPtr rp; + rrScrPrivPtr pScrPriv; +#if RANDR_12_INTERFACE + RRModePtr mode; + RRCrtcPtr crtc; + RROutputPtr output; + xRRModeInfo modeInfo; + char name[64]; +#endif if (!RRScreenInit (pScreen)) return FALSE; - rp = rrGetScrPriv(pScreen); - rp->rrGetInfo = miRRGetInfo; - rp->rrSetConfig = miRRSetConfig; + pScrPriv = rrGetScrPriv(pScreen); + pScrPriv->rrGetInfo = miRRGetInfo; +#if RANDR_12_INTERFACE + pScrPriv->rrCrtcSet = miRRCrtcSet; + pScrPriv->rrCrtcSetGamma = miRRCrtcSetGamma; + pScrPriv->rrOutputSetProperty = miRROutputSetProperty; + pScrPriv->rrOutputValidateMode = miRROutputValidateMode; + pScrPriv->rrModeDestroy = miRRModeDestroy; + + RRScreenSetSizeRange (pScreen, + pScreen->width, pScreen->height, + pScreen->width, pScreen->height); + + sprintf (name, "%dx%d", pScreen->width, pScreen->height); + memset (&modeInfo, '\0', sizeof (modeInfo)); + modeInfo.width = pScreen->width; + modeInfo.height = pScreen->height; + modeInfo.nameLength = strlen (name); + + mode = RRModeGet (&modeInfo, name); + if (!mode) + return FALSE; + + crtc = RRCrtcCreate (pScreen, NULL); + if (!crtc) + return FALSE; + + output = RROutputCreate (pScreen, "screen", 6, NULL); + if (!output) + return FALSE; + if (!RROutputSetClones (output, NULL, 0)) + return FALSE; + if (!RROutputSetModes (output, &mode, 1, 0)) + return FALSE; + if (!RROutputSetCrtcs (output, &crtc, 1)) + return FALSE; + if (!RROutputSetConnection (output, RR_Connected)) + return FALSE; + RRCrtcNotify (crtc, mode, 0, 0, RR_Rotate_0, 1, &output); +#endif return TRUE; } diff --git a/include/extensions/panoramiXproto.h b/programs/Xserver/randr/panoramiXproto.h similarity index 100% copy from include/extensions/panoramiXproto.h copy to programs/Xserver/randr/panoramiXproto.h diff --git a/include/extensions/panoramiXproto.h b/programs/Xserver/randr/panoramiXproto.h.NX.original similarity index 100% copy from include/extensions/panoramiXproto.h copy to programs/Xserver/randr/panoramiXproto.h.NX.original diff --git a/CHANGELOG.X.original b/programs/Xserver/randr/panoramiXproto.h.X.original similarity index 100% copy from CHANGELOG.X.original copy to programs/Xserver/randr/panoramiXproto.h.X.original diff --git a/programs/Xserver/randr/randr.c b/programs/Xserver/randr/randr.c index 3911a34..81df406 100644 --- a/programs/Xserver/randr/randr.c +++ b/programs/Xserver/randr/randr.c @@ -1,29 +1,46 @@ /* - * $XFree86: xc/programs/Xserver/randr/randr.c,v 1.21tsi Exp $ - * - * Copyright © 2000, Compaq Computer Corporation, - * Copyright © 2002, Hewlett Packard, Inc. + * Copyright © 2000 Compaq Computer Corporation + * Copyright © 2002 Hewlett-Packard Company + * Copyright © 2006 Intel Corporation * * 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 Compaq or HP not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. HP makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. + * 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. * - * HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL HP - * 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. + * 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. * - * Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc. + * Author: Jim Gettys, Hewlett-Packard Company, Inc. + * Keith Packard, Intel Corporation */ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */ +/* */ +/* NX-X11, NX protocol compression and NX extensions to this software */ +/* are copyright of NoMachine. Redistribution and use of the present */ +/* software is allowed according to terms specified in the file LICENSE */ +/* which comes in the source distribution. */ +/* */ +/* Check http://www.nomachine.com/licensing.html for applicability. */ +/* */ +/* NX and NoMachine are trademarks of Medialogic S.p.A. */ +/* */ +/* All rights reserved. */ +/* */ +/**************************************************************************/ #define NEED_REPLIES #define NEED_EVENTS @@ -31,28 +48,7 @@ #include <dix-config.h> #endif -#include <X11/X.h> -#include <X11/Xproto.h> -#include "misc.h" -#include "os.h" -#include "dixstruct.h" -#include "resource.h" -#include "scrnintstr.h" -#include "windowstr.h" -#include "pixmapstr.h" -#include "extnsionst.h" -#include "servermd.h" -#include <X11/extensions/randr.h> -#include <X11/extensions/randrproto.h> #include "randrstr.h" -#ifdef RENDER -#include <X11/extensions/render.h> /* we share subpixel order information */ -#include "picturestr.h" -#endif -#include <X11/Xfuncproto.h> -#ifdef EXTMODULE -#include "xf86_ansic.h" -#endif /* From render.h */ #ifndef SubPixelUnknown @@ -60,13 +56,7 @@ #endif #define RR_VALIDATE -int RRGeneration; -int RRNScreens; - -static int ProcRRQueryVersion (ClientPtr pClient); -static int ProcRRDispatch (ClientPtr pClient); -static int SProcRRDispatch (ClientPtr pClient); -static int SProcRRQueryVersion (ClientPtr pClient); +static int RRNScreens; #define wrap(priv,real,mem,func) {\ priv->mem = real->mem; \ @@ -77,56 +67,20 @@ static int SProcRRQueryVersion (ClientPtr pClient); real->mem = priv->mem; \ } -#if 0 -static CARD8 RRReqCode; -static int RRErrBase; -#endif -static int RREventBase; -static RESTYPE ClientType, EventType; /* resource types for event masks */ -static int RRClientPrivateIndex; - -typedef struct _RRTimes { - TimeStamp setTime; - TimeStamp configTime; -} RRTimesRec, *RRTimesPtr; - -typedef struct _RRClient { - int major_version; - int minor_version; -/* RRTimesRec times[0]; */ -} RRClientRec, *RRClientPtr; - -/* - * each window has a list of clients requesting - * RRNotify events. Each client has a resource - * for each window it selects RRNotify input for, - * this resource is used to delete the RRNotifyRec - * entry from the per-window queue. - */ - -typedef struct _RREvent *RREventPtr; +static int ProcRRDispatch (ClientPtr pClient); +static int SProcRRDispatch (ClientPtr pClient); -typedef struct _RREvent { - RREventPtr next; - ClientPtr client; - WindowPtr window; - XID clientResource; - int mask; -} RREventRec; +int RREventBase; +int RRErrorBase; +RESTYPE RRClientType, RREventType; /* resource types for event masks */ +#ifndef NXAGENT_SERVER +DevPrivateKey RRClientPrivateKey = &RRClientPrivateKey; +DevPrivateKey rrPrivKey = &rrPrivKey; +#else +int RRClientPrivateIndex; int rrPrivIndex = -1; - -#define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr) -#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient) - -static Bool -RRClientKnowsRates (ClientPtr pClient) -{ - rrClientPriv(pClient); - - return (pRRClient->major_version > 1 || - (pRRClient->major_version == 1 && pRRClient->minor_version >= 1)); -} +#endif static void RRClientCallback (CallbackListPtr *list, @@ -163,10 +117,14 @@ static Bool RRCloseScreen (int i, ScreenPtr pScreen) { rrScrPriv(pScreen); + int j; unwrap (pScrPriv, pScreen, CloseScreen); - if (pScrPriv->pSizes) - xfree (pScrPriv->pSizes); + for (j = pScrPriv->numCrtcs - 1; j >= 0; j--) + RRCrtcDestroy (pScrPriv->crtcs[j]); + for (j = pScrPriv->numOutputs - 1; j >= 0; j--) + RROutputDestroy (pScrPriv->outputs[j]); + xfree (pScrPriv); RRNScreens -= 1; /* ok, one fewer screen with RandR running */ return (*pScreen->CloseScreen) (i, pScreen); @@ -191,18 +149,105 @@ SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from, cpswaps(from->subpixelOrder, to->subpixelOrder); } -Bool RRScreenInit(ScreenPtr pScreen) +static void +SRRCrtcChangeNotifyEvent(xRRCrtcChangeNotifyEvent *from, + xRRCrtcChangeNotifyEvent *to) { - rrScrPrivPtr pScrPriv; + 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->crtc, to->crtc); + cpswapl(from->mode, to->mode); + cpswapl(from->window, to->window); + cpswaps(from->rotation, to->rotation); + cpswaps(from->x, to->x); + cpswaps(from->y, to->y); + cpswaps(from->width, to->width); + cpswaps(from->height, to->height); +} +static void +SRROutputChangeNotifyEvent(xRROutputChangeNotifyEvent *from, + xRROutputChangeNotifyEvent *to) +{ + to->type = from->type; + to->subCode = from->subCode; + cpswaps(from->sequenceNumber, to->sequenceNumber); + cpswapl(from->timestamp, to->timestamp); + cpswapl(from->configTimestamp, to->configTimestamp); + cpswapl(from->window, to->window); + cpswapl(from->output, to->output); + cpswapl(from->crtc, to->crtc); + cpswapl(from->mode, to->mode); + cpswaps(from->rotation, to->rotation); +} + +static void +SRROutputPropertyNotifyEvent(xRROutputPropertyNotifyEvent *from, + xRROutputPropertyNotifyEvent *to) +{ + to->type = from->type; + to->subCode = from->subCode; + cpswaps(from->sequenceNumber, to->sequenceNumber); + cpswapl(from->window, to->window); + cpswapl(from->output, to->output); + cpswapl(from->atom, to->atom); + cpswapl(from->timestamp, to->timestamp); +} + +static void +SRRNotifyEvent (xEvent *from, + xEvent *to) +{ + switch (from->u.u.detail) { + case RRNotify_CrtcChange: + SRRCrtcChangeNotifyEvent ((xRRCrtcChangeNotifyEvent *) from, + (xRRCrtcChangeNotifyEvent *) to); + break; + case RRNotify_OutputChange: + SRROutputChangeNotifyEvent ((xRROutputChangeNotifyEvent *) from, + (xRROutputChangeNotifyEvent *) to); + break; + case RRNotify_OutputProperty: + SRROutputPropertyNotifyEvent ((xRROutputPropertyNotifyEvent *) from, + (xRROutputPropertyNotifyEvent *) to); + break; + default: + break; + } +} + +static int RRGeneration; + +Bool RRInit (void) +{ if (RRGeneration != serverGeneration) { + #ifdef NXAGENT_SERVER if ((rrPrivIndex = AllocateScreenPrivateIndex()) < 0) return FALSE; + #endif + if (!RRModeInit ()) + return FALSE; + if (!RRCrtcInit ()) + return FALSE; + if (!RROutputInit ()) + return FALSE; RRGeneration = serverGeneration; } + return TRUE; +} + +Bool RRScreenInit(ScreenPtr pScreen) +{ + rrScrPrivPtr pScrPriv; - pScrPriv = (rrScrPrivPtr) xalloc (sizeof (rrScrPrivRec)); + if (!RRInit ()) + return FALSE; + + pScrPriv = (rrScrPrivPtr) xcalloc (1, sizeof (rrScrPrivRec)); if (!pScrPriv) return FALSE; @@ -211,8 +256,31 @@ Bool RRScreenInit(ScreenPtr pScreen) /* * Calling function best set these function vectors */ - pScrPriv->rrSetConfig = 0; pScrPriv->rrGetInfo = 0; + pScrPriv->maxWidth = pScrPriv->minWidth = pScreen->width; + pScrPriv->maxHeight = pScrPriv->minHeight = pScreen->height; + + pScrPriv->width = pScreen->width; + pScrPriv->height = pScreen->height; + pScrPriv->mmWidth = pScreen->mmWidth; + pScrPriv->mmHeight = pScreen->mmHeight; +#if RANDR_12_INTERFACE + pScrPriv->rrScreenSetSize = NULL; + pScrPriv->rrCrtcSet = NULL; + pScrPriv->rrCrtcSetGamma = NULL; +#endif +#if RANDR_10_INTERFACE + pScrPriv->rrSetConfig = 0; + pScrPriv->rotations = RR_Rotate_0; + pScrPriv->reqWidth = pScreen->width; + pScrPriv->reqHeight = pScreen->height; + pScrPriv->nSizes = 0; + pScrPriv->pSizes = NULL; + pScrPriv->rotation = RR_Rotate_0; + pScrPriv->rate = 0; + pScrPriv->size = 0; +#endif + /* * This value doesn't really matter -- any client must call * GetScreenInfo before reading it which will automatically update @@ -223,14 +291,10 @@ Bool RRScreenInit(ScreenPtr pScreen) wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen); - pScrPriv->rotations = RR_Rotate_0; - - pScrPriv->nSizes = 0; - pScrPriv->nSizesInUse = 0; - pScrPriv->pSizes = 0; - - pScrPriv->rotation = RR_Rotate_0; - pScrPriv->size = -1; + pScrPriv->numOutputs = 0; + pScrPriv->outputs = NULL; + pScrPriv->numCrtcs = 0; + pScrPriv->crtcs = NULL; RRNScreens += 1; /* keep count of screens that implement randr */ return TRUE; @@ -246,7 +310,7 @@ RRFreeClient (pointer data, XID id) pRREvent = (RREventPtr) data; pWin = pRREvent->window; - pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, EventType); + pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, RREventType); if (pHead) { pPrev = 0; for (pCur = *pHead; pCur && pCur != pRREvent; pCur=pCur->next) @@ -272,7 +336,7 @@ RRFreeEvents (pointer data, XID id) pHead = (RREventPtr *) data; for (pCur = *pHead; pCur; pCur = pNext) { pNext = pCur->next; - FreeResource (pCur->clientResource, ClientType); + FreeResource (pCur->clientResource, RRClientType); xfree ((pointer) pCur); } xfree ((pointer) pHead); @@ -286,1034 +350,172 @@ RRExtensionInit (void) if (RRNScreens == 0) return; + #ifndef NXAGENT_SERVER + if (!dixRequestPrivate(RRClientPrivateKey, + sizeof (RRClientRec) + + screenInfo.numScreens * sizeof (RRTimesRec))) + return; + #else RRClientPrivateIndex = AllocateClientPrivateIndex (); if (!AllocateClientPrivate (RRClientPrivateIndex, sizeof (RRClientRec) + screenInfo.numScreens * sizeof (RRTimesRec))) return; + #endif if (!AddCallback (&ClientStateCallback, RRClientCallback, 0)) return; - ClientType = CreateNewResourceType(RRFreeClient); - if (!ClientType) + RRClientType = CreateNewResourceType(RRFreeClient); + if (!RRClientType) return; - EventType = CreateNewResourceType(RRFreeEvents); - if (!EventType) + RREventType = CreateNewResourceType(RRFreeEvents); + if (!RREventType) return; extEntry = AddExtension (RANDR_NAME, RRNumberEvents, RRNumberErrors, ProcRRDispatch, SProcRRDispatch, RRResetProc, StandardMinorOpcode); if (!extEntry) return; -#if 0 - RRReqCode = (CARD8) extEntry->base; - RRErrBase = extEntry->errorBase; -#endif + RRErrorBase = extEntry->errorBase; RREventBase = extEntry->eventBase; EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr) - SRRScreenChangeNotifyEvent; - - return; + SRRScreenChangeNotifyEvent; + EventSwapVector[RREventBase + RRNotify] = (EventSwapPtr) + SRRNotifyEvent; +#ifdef PANORAMIX + RRXineramaExtensionInit(); +#endif } - + static int TellChanged (WindowPtr pWin, pointer value) { RREventPtr *pHead, pRREvent; ClientPtr client; - xRRScreenChangeNotifyEvent se; ScreenPtr pScreen = pWin->drawable.pScreen; rrScrPriv(pScreen); - RRScreenSizePtr pSize; - WindowPtr pRoot = WindowTable[pScreen->myNum]; + int i; - pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, EventType); + pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, RREventType); if (!pHead) return WT_WALKCHILDREN; - se.type = RRScreenChangeNotify + RREventBase; - se.rotation = (CARD8) pScrPriv->rotation; - se.timestamp = pScrPriv->lastSetTime.milliseconds; - 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; -#endif - if (pScrPriv->size >= 0) - { - pSize = &pScrPriv->pSizes[pScrPriv->size]; - se.sizeID = pSize->id; - se.widthInPixels = pSize->width; - se.heightInPixels = pSize->height; - se.widthInMillimeters = pSize->mmWidth; - se.heightInMillimeters = pSize->mmHeight; - } - else - { - /* - * This "shouldn't happen", but a broken DDX can - * forget to set the current configuration on GetInfo - */ - se.sizeID = 0xffff; - se.widthInPixels = 0; - se.heightInPixels = 0; - se.widthInMillimeters = 0; - se.heightInMillimeters = 0; - } for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) { client = pRREvent->client; if (client == serverClient || client->clientGone) continue; - se.sequenceNumber = client->sequence; - if(pRREvent->mask & RRScreenChangeNotifyMask) - WriteEventsToClient (client, 1, (xEvent *) &se); - } - return WT_WALKCHILDREN; -} - -static Bool -RRGetInfo (ScreenPtr pScreen) -{ - rrScrPriv (pScreen); - int i, j, k, l; - Bool changed; - Rotation rotations; - RRScreenSizePtr pSize; - RRScreenRatePtr pRate; - - for (i = 0; i < pScrPriv->nSizes; i++) - { - pSize = &pScrPriv->pSizes[i]; - pSize->oldReferenced = pSize->referenced; - pSize->referenced = FALSE; - for (k = 0; k < pSize->nRates; k++) - { - pRate = &pSize->pRates[k]; - pRate->oldReferenced = pRate->referenced; - pRate->referenced = FALSE; - } - } - if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations)) - return FALSE; - - changed = FALSE; - - /* - * Check whether anything changed and simultaneously generate - * the protocol id values for the objects - */ - if (rotations != pScrPriv->rotations) - { - pScrPriv->rotations = rotations; - changed = TRUE; - } - - j = 0; - for (i = 0; i < pScrPriv->nSizes; i++) - { - pSize = &pScrPriv->pSizes[i]; - if (pSize->oldReferenced != pSize->referenced) - changed = TRUE; - if (pSize->referenced) - pSize->id = j++; - l = 0; - for (k = 0; k < pSize->nRates; k++) - { - pRate = &pSize->pRates[k]; - if (pRate->oldReferenced != pRate->referenced) - changed = TRUE; - if (pRate->referenced) - l++; - } - pSize->nRatesInUse = l; - } - pScrPriv->nSizesInUse = j; - if (changed) - { - UpdateCurrentTime (); - pScrPriv->lastConfigTime = currentTime; - WalkTree (pScreen, TellChanged, (pointer) pScreen); - } - return TRUE; -} -static void -RRSendConfigNotify (ScreenPtr pScreen) -{ - WindowPtr pWin = WindowTable[pScreen->myNum]; - xEvent event; - - 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); -} - -static int -ProcRRQueryVersion (ClientPtr client) -{ - xRRQueryVersionReply rep; - register int n; - 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; - rep.majorVersion = RANDR_MAJOR; - rep.minorVersion = RANDR_MINOR; - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.majorVersion, n); - swapl(&rep.minorVersion, n); - } - WriteToClient(client, sizeof(xRRQueryVersionReply), (char *)&rep); - return (client->noClientException); -} - - -extern char *ConnectionInfo; - -static int padlength[4] = {0, 3, 2, 1}; - -static void -RREditConnectionInfo (ScreenPtr pScreen) -{ - xConnSetup *connSetup; - char *vendor; - xPixmapFormat *formats; - xWindowRoot *root; - xDepth *depth; - xVisualType *visual; - int screen = 0; - int d; - - connSetup = (xConnSetup *) ConnectionInfo; - vendor = (char *) connSetup + sizeof (xConnSetup); - formats = (xPixmapFormat *) ((char *) vendor + - connSetup->nbytesVendor + - padlength[connSetup->nbytesVendor & 3]); - root = (xWindowRoot *) ((char *) formats + - sizeof (xPixmapFormat) * screenInfo.numPixmapFormats); - while (screen != pScreen->myNum) - { - depth = (xDepth *) ((char *) root + - sizeof (xWindowRoot)); - for (d = 0; d < root->nDepths; d++) + if (pRREvent->mask & RRScreenChangeNotifyMask) + RRDeliverScreenEvent (client, pWin, pScreen); + + if (pRREvent->mask & RRCrtcChangeNotifyMask) { - visual = (xVisualType *) ((char *) depth + - sizeof (xDepth)); - depth = (xDepth *) ((char *) visual + - depth->nVisuals * sizeof (xVisualType)); - } - root = (xWindowRoot *) ((char *) depth); - screen++; - } - root->pixWidth = pScreen->width; - root->pixHeight = pScreen->height; - root->mmWidth = pScreen->mmWidth; - root->mmHeight = pScreen->mmHeight; -} - -static int -ProcRRGetScreenInfo (ClientPtr client) -{ - REQUEST(xRRGetScreenInfoReq); - xRRGetScreenInfoReply rep; - WindowPtr pWin; - int n; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - CARD8 *extra; - unsigned long extraLen; - - REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); - pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, - SecurityReadAccess); - - if (!pWin) - return BadWindow; - - pScreen = pWin->drawable.pScreen; - pScrPriv = rrGetScrPriv(pScreen); - rep.pad = 0; - if (!pScrPriv) - { - 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; - extra = 0; - extraLen = 0; - } - else - { - int i, j; - xScreenSizes *size; - CARD16 *rates; - CARD8 *data8; - Bool has_rate = RRClientKnowsRates (client); - - RRGetInfo (pScreen); - - rep.type = X_Reply; - rep.setOfRotations = pScrPriv->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 = pScrPriv->rotation; - rep.nSizes = pScrPriv->nSizesInUse; - rep.rate = pScrPriv->rate; - rep.nrateEnts = 0; - if (has_rate) - { - for (i = 0; i < pScrPriv->nSizes; i++) + for (i = 0; i < pScrPriv->numCrtcs; i++) { - RRScreenSizePtr pSize = &pScrPriv->pSizes[i]; - if (pSize->referenced) - { - rep.nrateEnts += (1 + pSize->nRatesInUse); - } + RRCrtcPtr crtc = pScrPriv->crtcs[i]; + if (crtc->changed) + RRDeliverCrtcEvent (client, pWin, crtc); } } - - if (pScrPriv->size >= 0) - rep.sizeID = pScrPriv->pSizes[pScrPriv->size].id; - else - return BadImplementation; - - extraLen = (rep.nSizes * sizeof (xScreenSizes) + - rep.nrateEnts * sizeof (CARD16)); - - extra = (CARD8 *) xalloc (extraLen); - if (!extra) - return BadAlloc; - /* - * First comes the size information - */ - size = (xScreenSizes *) extra; - rates = (CARD16 *) (size + rep.nSizes); - for (i = 0; i < pScrPriv->nSizes; i++) + + if (pRREvent->mask & RROutputChangeNotifyMask) { - RRScreenSizePtr pSize = &pScrPriv->pSizes[i]; - if (pSize->referenced) + for (i = 0; i < pScrPriv->numOutputs; i++) { - size->widthInPixels = pSize->width; - size->heightInPixels = pSize->height; - size->widthInMillimeters = pSize->mmWidth; - size->heightInMillimeters = pSize->mmHeight; - if (client->swapped) - { - swaps (&size->widthInPixels, n); - swaps (&size->heightInPixels, n); - swaps (&size->widthInMillimeters, n); - swaps (&size->heightInMillimeters, n); - } - size++; - if (has_rate) - { - *rates = pSize->nRatesInUse; - if (client->swapped) - { - swaps (rates, n); - } - rates++; - for (j = 0; j < pSize->nRates; j++) - { - RRScreenRatePtr pRate = &pSize->pRates[j]; - if (pRate->referenced) - { - *rates = pRate->rate; - if (client->swapped) - { - swaps (rates, n); - } - rates++; - } - } - } + RROutputPtr output = pScrPriv->outputs[i]; + if (output->changed) + RRDeliverOutputEvent (client, pWin, output); } } - data8 = (CARD8 *) rates; - - if (data8 - (CARD8 *) extra != extraLen) - FatalError ("RRGetScreenInfo bad extra len %ld != %ld\n", - (unsigned long)(data8 - (CARD8 *) extra), extraLen); - rep.length = (extraLen + 3) >> 2; - } - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.timestamp, n); - swaps(&rep.rotation, n); - swaps(&rep.nSizes, n); - swaps(&rep.sizeID, n); - swaps(&rep.rate, n); - swaps(&rep.nrateEnts, n); - } - WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *)&rep); - if (extraLen) - { - WriteToClient (client, extraLen, (char *) extra); - xfree (extra); } - return (client->noClientException); + return WT_WALKCHILDREN; } -static int -ProcRRSetScreenConfig (ClientPtr client) +/* + * Something changed; send events and adjust pointer position + */ +void +RRTellChanged (ScreenPtr pScreen) { - REQUEST(xRRSetScreenConfigReq); - xRRSetScreenConfigReply rep; - DrawablePtr pDraw; - int n; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - TimeStamp configTime; - TimeStamp time; - RRScreenSizePtr pSize; - int i; - Rotation rotation; - int rate; - short oldWidth, oldHeight; - Bool has_rate; - - UpdateCurrentTime (); - - if (RRClientKnowsRates (client)) - { - REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); - has_rate = TRUE; - } - else - { - REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); - has_rate = FALSE; - } - - SECURITY_VERIFY_DRAWABLE(pDraw, stuff->drawable, client, - SecurityWriteAccess); - - pScreen = pDraw->pScreen; - - pScrPriv = rrGetScrPriv(pScreen); - - time = ClientTimeToServerTime(stuff->timestamp); - configTime = ClientTimeToServerTime(stuff->configTimestamp); - - oldWidth = pScreen->width; - oldHeight = pScreen->height; - - if (!pScrPriv) - { - time = currentTime; - rep.status = RRSetConfigFailed; - goto sendReply; - } - if (!RRGetInfo (pScreen)) - return BadAlloc; - - /* - * if the client's config timestamp is not the same as the last config - * timestamp, then the config information isn't up-to-date and - * can't even be validated - */ - if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0) - { - rep.status = RRSetConfigInvalidConfigTime; - goto sendReply; - } - - /* - * Search for the requested size - */ - pSize = 0; - for (i = 0; i < pScrPriv->nSizes; i++) - { - pSize = &pScrPriv->pSizes[i]; - if (pSize->referenced && pSize->id == stuff->sizeID) - { - break; - } - } - if (i == pScrPriv->nSizes) - { - /* - * Invalid size ID - */ - client->errorValue = stuff->sizeID; - return BadValue; - } + rrScrPriv (pScreen); + int i; - /* - * Validate requested rotation - */ - rotation = (Rotation) stuff->rotation; - - /* test the rotation bits only! */ - switch (rotation & 0xf) { - case RR_Rotate_0: - case RR_Rotate_90: - case RR_Rotate_180: - case RR_Rotate_270: - break; - default: - /* - * Invalid rotation - */ - client->errorValue = stuff->rotation; - return BadValue; - } - - if ((~pScrPriv->rotations) & rotation) - { - /* - * requested rotation or reflection not supported by screen - */ - client->errorValue = stuff->rotation; - return BadMatch; - } - - /* - * Validate requested refresh - */ - if (has_rate) - rate = (int) stuff->rate; - else - rate = 0; - - if (rate) + if (pScrPriv->changed) { - for (i = 0; i < pSize->nRates; i++) + UpdateCurrentTime (); + if (pScrPriv->configChanged) { - RRScreenRatePtr pRate = &pSize->pRates[i]; - if (pRate->referenced && pRate->rate == rate) - break; + pScrPriv->lastConfigTime = currentTime; + pScrPriv->configChanged = FALSE; } - if (i == pSize->nRates) + pScrPriv->changed = FALSE; + WalkTree (pScreen, TellChanged, (pointer) pScreen); + 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) { - /* - * Invalid rate - */ - client->errorValue = rate; - return BadValue; + pScrPriv->layoutChanged = FALSE; + RRPointerScreenConfigured (pScreen); + RRSendConfigNotify (pScreen); } } - - /* - * 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; - } - - /* - * call out to ddx routine to effect the change - */ - if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate, - pSize)) - { - /* - * unknown DDX failure, report to client - */ - rep.status = RRSetConfigFailed; - goto sendReply; - } - - /* - * set current extension configuration pointers - */ - RRSetCurrentConfig (pScreen, rotation, rate, pSize); - - /* - * Deliver ScreenChangeNotify events whenever - * the configuration is updated - */ - WalkTree (pScreen, TellChanged, (pointer) pScreen); - - /* - * Deliver ConfigureNotify events when root changes - * pixel size - */ - if (oldWidth != pScreen->width || oldHeight != pScreen->height) - RRSendConfigNotify (pScreen); - RREditConnectionInfo (pScreen); - - /* - * Fix pointer bounds and location - */ - ScreenRestructured (pScreen); - pScrPriv->lastSetTime = time; - - /* - * Report Success - */ - rep.status = RRSetConfigSuccess; - -sendReply: - - rep.type = X_Reply; - /* rep.status has already been filled in */ - rep.length = 0; - rep.sequenceNumber = client->sequence; - - rep.newTimestamp = pScrPriv->lastSetTime.milliseconds; - rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds; - rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id; - - if (client->swapped) - { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.newTimestamp, n); - swapl(&rep.newConfigTimestamp, n); - swapl(&rep.root, n); - } - WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *)&rep); - - return (client->noClientException); } -int -RRSetScreenConfig (ScreenPtr pScreen, - Rotation rotation, - int rate, - RRScreenSizePtr pSize) +/* + * Return the first output which is connected to an active CRTC + * Used in emulating 1.0 behaviour + */ +RROutputPtr +RRFirstOutput (ScreenPtr pScreen) { - rrScrPrivPtr pScrPriv; - int i; - short oldWidth, oldHeight; - - pScrPriv = rrGetScrPriv(pScreen); - - oldWidth = pScreen->width; - oldHeight = pScreen->height; - - if (!RRGetInfo (pScreen)) - return BadAlloc; + rrScrPriv(pScreen); + RROutputPtr output; + int i, j; - /* - * Validate requested rotation - */ - - /* test the rotation bits only! */ - switch (rotation & 0xf) { - case RR_Rotate_0: - case RR_Rotate_90: - case RR_Rotate_180: - case RR_Rotate_270: - break; - default: - /* - * Invalid rotation - */ - return BadValue; - } - - if ((~pScrPriv->rotations) & rotation) + for (i = 0; i < pScrPriv->numCrtcs; i++) { - /* - * requested rotation or reflection not supported by screen - */ - return BadMatch; - } - - /* - * Validate requested refresh - */ - if (rate) - { - for (i = 0; i < pSize->nRates; i++) + RRCrtcPtr crtc = pScrPriv->crtcs[i]; + for (j = 0; j < pScrPriv->numOutputs; j++) { - RRScreenRatePtr pRate = &pSize->pRates[i]; - if (pRate->referenced && pRate->rate == rate) - break; + output = pScrPriv->outputs[j]; + if (output->crtc == crtc) + return output; } - if (i == pSize->nRates) - { - /* - * Invalid rate - */ - return BadValue; - } - } - - /* - * call out to ddx routine to effect the change - */ - if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate, - pSize)) - { - /* - * unknown DDX failure, report to client - */ - return BadImplementation; } - - /* - * set current extension configuration pointers - */ - RRSetCurrentConfig (pScreen, rotation, rate, pSize); - - /* - * Deliver ScreenChangeNotify events whenever - * the configuration is updated - */ - WalkTree (pScreen, TellChanged, (pointer) pScreen); - - /* - * Deliver ConfigureNotify events when root changes - * pixel size - */ - if (oldWidth != pScreen->width || oldHeight != pScreen->height) - RRSendConfigNotify (pScreen); - RREditConnectionInfo (pScreen); - - /* - * Fix pointer bounds and location - */ - ScreenRestructured (pScreen); - - return Success; + return NULL; } -static int -ProcRRSelectInput (ClientPtr client) +CARD16 +RRVerticalRefresh (xRRModeInfo *mode) { - REQUEST(xRRSelectInputReq); - rrClientPriv(client); - RRTimesPtr pTimes; - WindowPtr pWin; - RREventPtr pRREvent, pNewRREvent, *pHead; - XID clientResource; - - REQUEST_SIZE_MATCH(xRRSelectInputReq); - pWin = SecurityLookupWindow (stuff->window, client, SecurityWriteAccess); - if (!pWin) - return BadWindow; - pHead = (RREventPtr *)SecurityLookupIDByType(client, - pWin->drawable.id, EventType, - SecurityWriteAccess); - - if (stuff->enable & (RRScreenChangeNotifyMask)) - { - ScreenPtr pScreen = pWin->drawable.pScreen; - rrScrPriv (pScreen); - - if (pHead) - { - /* check for existing entry. */ - for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) - if (pRREvent->client == client) - return Success; - } - - /* build the entry */ - pNewRREvent = (RREventPtr) xalloc (sizeof (RREventRec)); - if (!pNewRREvent) - return BadAlloc; - pNewRREvent->next = 0; - pNewRREvent->client = client; - pNewRREvent->window = pWin; - pNewRREvent->mask = stuff->enable; - /* - * add a resource that will be deleted when - * the client goes away - */ - clientResource = FakeClientID (client->index); - pNewRREvent->clientResource = clientResource; - if (!AddResource (clientResource, ClientType, (pointer)pNewRREvent)) - return BadAlloc; - /* - * create a resource to contain a pointer to the list - * of clients selecting input. This must be indirect as - * the list may be arbitrarily rearranged which cannot be - * done through the resource database. - */ - if (!pHead) - { - pHead = (RREventPtr *) xalloc (sizeof (RREventPtr)); - if (!pHead || - !AddResource (pWin->drawable.id, EventType, (pointer)pHead)) - { - FreeResource (clientResource, RT_NONE); - return BadAlloc; - } - *pHead = 0; - } - pNewRREvent->next = *pHead; - *pHead = pNewRREvent; - /* - * Now see if the client needs an event - */ - if (pScrPriv) - { - pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum]; - if (CompareTimeStamps (pTimes->setTime, - pScrPriv->lastSetTime) != 0 || - CompareTimeStamps (pTimes->configTime, - pScrPriv->lastConfigTime) != 0) - { - TellChanged (pWin, (pointer) pScreen); - } - } - } - else if (stuff->enable == xFalse) - { - /* delete the interest */ - if (pHead) { - pNewRREvent = 0; - for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) { - if (pRREvent->client == client) - break; - pNewRREvent = pRREvent; - } - if (pRREvent) { - FreeResource (pRREvent->clientResource, ClientType); - if (pNewRREvent) - pNewRREvent->next = pRREvent->next; - else - *pHead = pRREvent->next; - xfree (pRREvent); - } - } - } - else - { - client->errorValue = stuff->enable; - return BadValue; - } - return Success; + CARD32 refresh; + CARD32 dots = mode->hTotal * mode->vTotal; + if (!dots) + return 0; + refresh = (mode->dotClock + dots/2) / dots; + if (refresh > 0xffff) + refresh = 0xffff; + return (CARD16) refresh; } - static int ProcRRDispatch (ClientPtr client) { REQUEST(xReq); - switch (stuff->data) - { - case X_RRQueryVersion: - return ProcRRQueryVersion(client); - case X_RRSetScreenConfig: - return ProcRRSetScreenConfig(client); - case X_RRSelectInput: - return ProcRRSelectInput(client); - case X_RRGetScreenInfo: - return ProcRRGetScreenInfo(client); - default: + if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data]) return BadRequest; - } -} - -static int -SProcRRQueryVersion (ClientPtr client) -{ - register int n; - REQUEST(xRRQueryVersionReq); - - swaps(&stuff->length, n); - swapl(&stuff->majorVersion, n); - swapl(&stuff->minorVersion, n); - return ProcRRQueryVersion(client); -} - -static int -SProcRRGetScreenInfo (ClientPtr client) -{ - register int n; - REQUEST(xRRGetScreenInfoReq); - - swaps(&stuff->length, n); - swapl(&stuff->window, n); - return ProcRRGetScreenInfo(client); -} - -static int -SProcRRSetScreenConfig (ClientPtr client) -{ - register int n; - REQUEST(xRRSetScreenConfigReq); - - if (RRClientKnowsRates (client)) - { - REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); - swaps (&stuff->rate, n); - } - else - { - REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); - } - - swaps(&stuff->length, n); - swapl(&stuff->drawable, n); - swapl(&stuff->timestamp, n); - swaps(&stuff->sizeID, n); - swaps(&stuff->rotation, n); - return ProcRRSetScreenConfig(client); -} - -static int -SProcRRSelectInput (ClientPtr client) -{ - register int n; - REQUEST(xRRSelectInputReq); - - swaps(&stuff->length, n); - swapl(&stuff->window, n); - return ProcRRSelectInput(client); + return (*ProcRandrVector[stuff->data]) (client); } - static int SProcRRDispatch (ClientPtr client) { REQUEST(xReq); - switch (stuff->data) - { - case X_RRQueryVersion: - return SProcRRQueryVersion(client); - case X_RRSetScreenConfig: - return SProcRRSetScreenConfig(client); - case X_RRSelectInput: - return SProcRRSelectInput(client); - case X_RRGetScreenInfo: - return SProcRRGetScreenInfo(client); - default: + if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data]) return BadRequest; - } + return (*SProcRandrVector[stuff->data]) (client); } - -static Bool -RRScreenSizeMatches (RRScreenSizePtr a, - RRScreenSizePtr b) -{ - if (a->width != b->width) - return FALSE; - if (a->height != b->height) - return FALSE; - if (a->mmWidth != b->mmWidth) - return FALSE; - if (a->mmHeight != b->mmHeight) - return FALSE; - return TRUE; -} - -RRScreenSizePtr -RRRegisterSize (ScreenPtr pScreen, - short width, - short height, - short mmWidth, - short mmHeight) -{ - rrScrPriv (pScreen); - int i; - RRScreenSize tmp; - RRScreenSizePtr pNew; - - if (!pScrPriv) - return 0; - - tmp.width = width; - tmp.height= height; - tmp.mmWidth = mmWidth; - tmp.mmHeight = mmHeight; - tmp.pRates = 0; - tmp.nRates = 0; - tmp.nRatesInUse = 0; - tmp.referenced = TRUE; - tmp.oldReferenced = FALSE; - for (i = 0; i < pScrPriv->nSizes; i++) - if (RRScreenSizeMatches (&tmp, &pScrPriv->pSizes[i])) - { - pScrPriv->pSizes[i].referenced = TRUE; - return &pScrPriv->pSizes[i]; - } - pNew = xrealloc (pScrPriv->pSizes, - (pScrPriv->nSizes + 1) * sizeof (RRScreenSize)); - if (!pNew) - return 0; - pNew[pScrPriv->nSizes++] = tmp; - pScrPriv->pSizes = pNew; - return &pNew[pScrPriv->nSizes-1]; -} - -Bool RRRegisterRate (ScreenPtr pScreen, - RRScreenSizePtr pSize, - int rate) -{ - rrScrPriv(pScreen); - int i; - RRScreenRatePtr pNew, pRate; - - if (!pScrPriv) - return FALSE; - - for (i = 0; i < pSize->nRates; i++) - { - pRate = &pSize->pRates[i]; - if (pRate->rate == rate) - { - pRate->referenced = TRUE; - return TRUE; - } - } - - pNew = xrealloc (pSize->pRates, - (pSize->nRates + 1) * sizeof (RRScreenRate)); - if (!pNew) - return FALSE; - pRate = &pNew[pSize->nRates++]; - pRate->rate = rate; - pRate->referenced = TRUE; - pRate->oldReferenced = FALSE; - pSize->pRates = pNew; - return TRUE; -} - -void -RRSetCurrentConfig (ScreenPtr pScreen, - Rotation rotation, - int rate, - RRScreenSizePtr pSize) -{ - rrScrPriv (pScreen); - - if (!pScrPriv) - return; - - pScrPriv->rotation = rotation; - pScrPriv->size = pSize - pScrPriv->pSizes; - pScrPriv->rate = rate; -} diff --git a/programs/Xserver/randr/randr.c.NX.original b/programs/Xserver/randr/randr.c.NX.original new file mode 100644 index 0000000..81df406 --- /dev/null +++ b/programs/Xserver/randr/randr.c.NX.original @@ -0,0 +1,521 @@ +/* + * Copyright © 2000 Compaq Computer Corporation + * Copyright © 2002 Hewlett-Packard Company + * Copyright © 2006 Intel Corporation + * + * 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. + * + * Author: Jim Gettys, Hewlett-Packard Company, Inc. + * Keith Packard, Intel Corporation + */ + +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */ +/* */ +/* NX-X11, NX protocol compression and NX extensions to this software */ +/* are copyright of NoMachine. Redistribution and use of the present */ +/* software is allowed according to terms specified in the file LICENSE */ +/* which comes in the source distribution. */ +/* */ +/* Check http://www.nomachine.com/licensing.html for applicability. */ +/* */ +/* NX and NoMachine are trademarks of Medialogic S.p.A. */ +/* */ +/* All rights reserved. */ +/* */ +/**************************************************************************/ + +#define NEED_REPLIES +#define NEED_EVENTS +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "randrstr.h" + +/* From render.h */ +#ifndef SubPixelUnknown +#define SubPixelUnknown 0 +#endif + +#define RR_VALIDATE +static int RRNScreens; + +#define wrap(priv,real,mem,func) {\ + priv->mem = real->mem; \ + real->mem = func; \ +} + +#define unwrap(priv,real,mem) {\ + real->mem = priv->mem; \ +} + +static int ProcRRDispatch (ClientPtr pClient); +static int SProcRRDispatch (ClientPtr pClient); + +int RREventBase; +int RRErrorBase; +RESTYPE RRClientType, RREventType; /* resource types for event masks */ + +#ifndef NXAGENT_SERVER +DevPrivateKey RRClientPrivateKey = &RRClientPrivateKey; +DevPrivateKey rrPrivKey = &rrPrivKey; +#else +int RRClientPrivateIndex; +int rrPrivIndex = -1; +#endif + +static void +RRClientCallback (CallbackListPtr *list, + pointer closure, + pointer data) +{ + NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; + ClientPtr pClient = clientinfo->client; + rrClientPriv(pClient); + RRTimesPtr pTimes = (RRTimesPtr) (pRRClient + 1); + int i; + + pRRClient->major_version = 0; + pRRClient->minor_version = 0; + for (i = 0; i < screenInfo.numScreens; i++) + { + ScreenPtr pScreen = screenInfo.screens[i]; + rrScrPriv(pScreen); + + if (pScrPriv) + { + pTimes[i].setTime = pScrPriv->lastSetTime; + pTimes[i].configTime = pScrPriv->lastConfigTime; + } + } +} + +static void +RRResetProc (ExtensionEntry *extEntry) +{ +} + +static Bool +RRCloseScreen (int i, ScreenPtr pScreen) +{ + rrScrPriv(pScreen); + int j; + + unwrap (pScrPriv, pScreen, CloseScreen); + for (j = pScrPriv->numCrtcs - 1; j >= 0; j--) + RRCrtcDestroy (pScrPriv->crtcs[j]); + for (j = pScrPriv->numOutputs - 1; j >= 0; j--) + RROutputDestroy (pScrPriv->outputs[j]); + + xfree (pScrPriv); + RRNScreens -= 1; /* ok, one fewer screen with RandR running */ + return (*pScreen->CloseScreen) (i, pScreen); +} + +static void +SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from, + xRRScreenChangeNotifyEvent *to) +{ + to->type = from->type; + to->rotation = from->rotation; + cpswaps(from->sequenceNumber, to->sequenceNumber); + cpswapl(from->timestamp, to->timestamp); + cpswapl(from->configTimestamp, to->configTimestamp); + cpswapl(from->root, to->root); + cpswapl(from->window, to->window); + cpswaps(from->sizeID, to->sizeID); + 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 +SRRCrtcChangeNotifyEvent(xRRCrtcChangeNotifyEvent *from, + xRRCrtcChangeNotifyEvent *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->crtc, to->crtc); + cpswapl(from->mode, to->mode); + cpswapl(from->window, to->window); + cpswaps(from->rotation, to->rotation); + cpswaps(from->x, to->x); + cpswaps(from->y, to->y); + cpswaps(from->width, to->width); + cpswaps(from->height, to->height); +} + +static void +SRROutputChangeNotifyEvent(xRROutputChangeNotifyEvent *from, + xRROutputChangeNotifyEvent *to) +{ + to->type = from->type; + to->subCode = from->subCode; + cpswaps(from->sequenceNumber, to->sequenceNumber); + cpswapl(from->timestamp, to->timestamp); + cpswapl(from->configTimestamp, to->configTimestamp); + cpswapl(from->window, to->window); + cpswapl(from->output, to->output); + cpswapl(from->crtc, to->crtc); + cpswapl(from->mode, to->mode); + cpswaps(from->rotation, to->rotation); +} + +static void +SRROutputPropertyNotifyEvent(xRROutputPropertyNotifyEvent *from, + xRROutputPropertyNotifyEvent *to) +{ + to->type = from->type; + to->subCode = from->subCode; + cpswaps(from->sequenceNumber, to->sequenceNumber); + cpswapl(from->window, to->window); + cpswapl(from->output, to->output); + cpswapl(from->atom, to->atom); + cpswapl(from->timestamp, to->timestamp); +} + +static void +SRRNotifyEvent (xEvent *from, + xEvent *to) +{ + switch (from->u.u.detail) { + case RRNotify_CrtcChange: + SRRCrtcChangeNotifyEvent ((xRRCrtcChangeNotifyEvent *) from, + (xRRCrtcChangeNotifyEvent *) to); + break; + case RRNotify_OutputChange: + SRROutputChangeNotifyEvent ((xRROutputChangeNotifyEvent *) from, + (xRROutputChangeNotifyEvent *) to); + break; + case RRNotify_OutputProperty: + SRROutputPropertyNotifyEvent ((xRROutputPropertyNotifyEvent *) from, + (xRROutputPropertyNotifyEvent *) to); + break; + default: + break; + } +} + +static int RRGeneration; + +Bool RRInit (void) +{ + if (RRGeneration != serverGeneration) + { + #ifdef NXAGENT_SERVER + if ((rrPrivIndex = AllocateScreenPrivateIndex()) < 0) + return FALSE; + #endif + if (!RRModeInit ()) + return FALSE; + if (!RRCrtcInit ()) + return FALSE; + if (!RROutputInit ()) + return FALSE; + RRGeneration = serverGeneration; + } + return TRUE; +} + +Bool RRScreenInit(ScreenPtr pScreen) +{ + rrScrPrivPtr pScrPriv; + + if (!RRInit ()) + return FALSE; + + pScrPriv = (rrScrPrivPtr) xcalloc (1, sizeof (rrScrPrivRec)); + if (!pScrPriv) + return FALSE; + + SetRRScreen(pScreen, pScrPriv); + + /* + * Calling function best set these function vectors + */ + pScrPriv->rrGetInfo = 0; + pScrPriv->maxWidth = pScrPriv->minWidth = pScreen->width; + pScrPriv->maxHeight = pScrPriv->minHeight = pScreen->height; + + pScrPriv->width = pScreen->width; + pScrPriv->height = pScreen->height; + pScrPriv->mmWidth = pScreen->mmWidth; + pScrPriv->mmHeight = pScreen->mmHeight; +#if RANDR_12_INTERFACE + pScrPriv->rrScreenSetSize = NULL; + pScrPriv->rrCrtcSet = NULL; + pScrPriv->rrCrtcSetGamma = NULL; +#endif +#if RANDR_10_INTERFACE + pScrPriv->rrSetConfig = 0; + pScrPriv->rotations = RR_Rotate_0; + pScrPriv->reqWidth = pScreen->width; + pScrPriv->reqHeight = pScreen->height; + pScrPriv->nSizes = 0; + pScrPriv->pSizes = NULL; + pScrPriv->rotation = RR_Rotate_0; + pScrPriv->rate = 0; + pScrPriv->size = 0; +#endif + + /* + * This value doesn't really matter -- any client must call + * GetScreenInfo before reading it which will automatically update + * the time + */ + pScrPriv->lastSetTime = currentTime; + pScrPriv->lastConfigTime = currentTime; + + wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen); + + pScrPriv->numOutputs = 0; + pScrPriv->outputs = NULL; + pScrPriv->numCrtcs = 0; + pScrPriv->crtcs = NULL; + + RRNScreens += 1; /* keep count of screens that implement randr */ + return TRUE; +} + +/*ARGSUSED*/ +static int +RRFreeClient (pointer data, XID id) +{ + RREventPtr pRREvent; + WindowPtr pWin; + RREventPtr *pHead, pCur, pPrev; + + pRREvent = (RREventPtr) data; + pWin = pRREvent->window; + pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, RREventType); + if (pHead) { + pPrev = 0; + for (pCur = *pHead; pCur && pCur != pRREvent; pCur=pCur->next) + pPrev = pCur; + if (pCur) + { + if (pPrev) + pPrev->next = pRREvent->next; + else + *pHead = pRREvent->next; + } + } + xfree ((pointer) pRREvent); + return 1; +} + +/*ARGSUSED*/ +static int +RRFreeEvents (pointer data, XID id) +{ + RREventPtr *pHead, pCur, pNext; + + pHead = (RREventPtr *) data; + for (pCur = *pHead; pCur; pCur = pNext) { + pNext = pCur->next; + FreeResource (pCur->clientResource, RRClientType); + xfree ((pointer) pCur); + } + xfree ((pointer) pHead); + return 1; +} + +void +RRExtensionInit (void) +{ + ExtensionEntry *extEntry; + + if (RRNScreens == 0) return; + + #ifndef NXAGENT_SERVER + if (!dixRequestPrivate(RRClientPrivateKey, + sizeof (RRClientRec) + + screenInfo.numScreens * sizeof (RRTimesRec))) + return; + #else + RRClientPrivateIndex = AllocateClientPrivateIndex (); + if (!AllocateClientPrivate (RRClientPrivateIndex, + sizeof (RRClientRec) + + screenInfo.numScreens * sizeof (RRTimesRec))) + return; + #endif + if (!AddCallback (&ClientStateCallback, RRClientCallback, 0)) + return; + + RRClientType = CreateNewResourceType(RRFreeClient); + if (!RRClientType) + return; + RREventType = CreateNewResourceType(RRFreeEvents); + if (!RREventType) + return; + extEntry = AddExtension (RANDR_NAME, RRNumberEvents, RRNumberErrors, + ProcRRDispatch, SProcRRDispatch, + RRResetProc, StandardMinorOpcode); + if (!extEntry) + return; + RRErrorBase = extEntry->errorBase; + RREventBase = extEntry->eventBase; + EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr) + SRRScreenChangeNotifyEvent; + EventSwapVector[RREventBase + RRNotify] = (EventSwapPtr) + SRRNotifyEvent; +#ifdef PANORAMIX + RRXineramaExtensionInit(); +#endif +} + +static int +TellChanged (WindowPtr pWin, pointer value) +{ + RREventPtr *pHead, pRREvent; + ClientPtr client; + ScreenPtr pScreen = pWin->drawable.pScreen; + rrScrPriv(pScreen); + int i; + + pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, RREventType); + if (!pHead) + return WT_WALKCHILDREN; + + for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) + { + client = pRREvent->client; + if (client == serverClient || client->clientGone) + continue; + + if (pRREvent->mask & RRScreenChangeNotifyMask) + RRDeliverScreenEvent (client, pWin, pScreen); + + if (pRREvent->mask & RRCrtcChangeNotifyMask) + { + for (i = 0; i < pScrPriv->numCrtcs; i++) + { + RRCrtcPtr crtc = pScrPriv->crtcs[i]; + if (crtc->changed) + RRDeliverCrtcEvent (client, pWin, crtc); + } + } + + if (pRREvent->mask & RROutputChangeNotifyMask) + { + for (i = 0; i < pScrPriv->numOutputs; i++) + { + RROutputPtr output = pScrPriv->outputs[i]; + if (output->changed) + RRDeliverOutputEvent (client, pWin, output); + } + } + } + return WT_WALKCHILDREN; +} + +/* + * Something changed; send events and adjust pointer position + */ +void +RRTellChanged (ScreenPtr pScreen) +{ + rrScrPriv (pScreen); + int i; + + if (pScrPriv->changed) + { + UpdateCurrentTime (); + if (pScrPriv->configChanged) + { + pScrPriv->lastConfigTime = currentTime; + pScrPriv->configChanged = FALSE; + } + pScrPriv->changed = FALSE; + WalkTree (pScreen, TellChanged, (pointer) pScreen); + 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) + { + pScrPriv->layoutChanged = FALSE; + RRPointerScreenConfigured (pScreen); + RRSendConfigNotify (pScreen); + } + } +} + +/* + * Return the first output which is connected to an active CRTC + * Used in emulating 1.0 behaviour + */ +RROutputPtr +RRFirstOutput (ScreenPtr pScreen) +{ + rrScrPriv(pScreen); + RROutputPtr output; + int i, j; + + for (i = 0; i < pScrPriv->numCrtcs; i++) + { + RRCrtcPtr crtc = pScrPriv->crtcs[i]; + for (j = 0; j < pScrPriv->numOutputs; j++) + { + output = pScrPriv->outputs[j]; + if (output->crtc == crtc) + return output; + } + } + return NULL; +} + +CARD16 +RRVerticalRefresh (xRRModeInfo *mode) +{ + CARD32 refresh; + CARD32 dots = mode->hTotal * mode->vTotal; + if (!dots) + return 0; + refresh = (mode->dotClock + dots/2) / dots; + if (refresh > 0xffff) + refresh = 0xffff; + return (CARD16) refresh; +} + +static int +ProcRRDispatch (ClientPtr client) +{ + REQUEST(xReq); + if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data]) + return BadRequest; + return (*ProcRandrVector[stuff->data]) (client); +} + +static int +SProcRRDispatch (ClientPtr client) +{ + REQUEST(xReq); + if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data]) + return BadRequest; + return (*SProcRandrVector[stuff->data]) (client); +} + diff --git a/programs/Xserver/randr/randr.c.X.original b/programs/Xserver/randr/randr.c.X.original new file mode 100644 index 0000000..bc2b995 --- /dev/null +++ b/programs/Xserver/randr/randr.c.X.original @@ -0,0 +1,487 @@ +/* + * Copyright © 2000 Compaq Computer Corporation + * Copyright © 2002 Hewlett-Packard Company + * Copyright © 2006 Intel Corporation + * + * 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. + * + * Author: Jim Gettys, Hewlett-Packard Company, Inc. + * Keith Packard, Intel Corporation + */ + +#define NEED_REPLIES +#define NEED_EVENTS +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "randrstr.h" + +/* From render.h */ +#ifndef SubPixelUnknown +#define SubPixelUnknown 0 +#endif + +#define RR_VALIDATE +static int RRNScreens; + +#define wrap(priv,real,mem,func) {\ + priv->mem = real->mem; \ + real->mem = func; \ +} + +#define unwrap(priv,real,mem) {\ + real->mem = priv->mem; \ +} + +static int ProcRRDispatch (ClientPtr pClient); +static int SProcRRDispatch (ClientPtr pClient); + +int RREventBase; +int RRErrorBase; +RESTYPE RRClientType, RREventType; /* resource types for event masks */ +DevPrivateKey RRClientPrivateKey = &RRClientPrivateKey; + +DevPrivateKey rrPrivKey = &rrPrivKey; + +static void +RRClientCallback (CallbackListPtr *list, + pointer closure, + pointer data) +{ + NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; + ClientPtr pClient = clientinfo->client; + rrClientPriv(pClient); + RRTimesPtr pTimes = (RRTimesPtr) (pRRClient + 1); + int i; + + pRRClient->major_version = 0; + pRRClient->minor_version = 0; + for (i = 0; i < screenInfo.numScreens; i++) + { + ScreenPtr pScreen = screenInfo.screens[i]; + rrScrPriv(pScreen); + + if (pScrPriv) + { + pTimes[i].setTime = pScrPriv->lastSetTime; + pTimes[i].configTime = pScrPriv->lastConfigTime; + } + } +} + +static void +RRResetProc (ExtensionEntry *extEntry) +{ +} + +static Bool +RRCloseScreen (int i, ScreenPtr pScreen) +{ + rrScrPriv(pScreen); + int j; + + unwrap (pScrPriv, pScreen, CloseScreen); + for (j = pScrPriv->numCrtcs - 1; j >= 0; j--) + RRCrtcDestroy (pScrPriv->crtcs[j]); + for (j = pScrPriv->numOutputs - 1; j >= 0; j--) + RROutputDestroy (pScrPriv->outputs[j]); + + xfree (pScrPriv); + RRNScreens -= 1; /* ok, one fewer screen with RandR running */ + return (*pScreen->CloseScreen) (i, pScreen); +} + +static void +SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from, + xRRScreenChangeNotifyEvent *to) +{ + to->type = from->type; + to->rotation = from->rotation; + cpswaps(from->sequenceNumber, to->sequenceNumber); + cpswapl(from->timestamp, to->timestamp); + cpswapl(from->configTimestamp, to->configTimestamp); + cpswapl(from->root, to->root); + cpswapl(from->window, to->window); + cpswaps(from->sizeID, to->sizeID); + 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 +SRRCrtcChangeNotifyEvent(xRRCrtcChangeNotifyEvent *from, + xRRCrtcChangeNotifyEvent *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->crtc, to->crtc); + cpswapl(from->mode, to->mode); + cpswapl(from->window, to->window); + cpswaps(from->rotation, to->rotation); + cpswaps(from->x, to->x); + cpswaps(from->y, to->y); + cpswaps(from->width, to->width); + cpswaps(from->height, to->height); +} + +static void +SRROutputChangeNotifyEvent(xRROutputChangeNotifyEvent *from, + xRROutputChangeNotifyEvent *to) +{ + to->type = from->type; + to->subCode = from->subCode; + cpswaps(from->sequenceNumber, to->sequenceNumber); + cpswapl(from->timestamp, to->timestamp); + cpswapl(from->configTimestamp, to->configTimestamp); + cpswapl(from->window, to->window); + cpswapl(from->output, to->output); + cpswapl(from->crtc, to->crtc); + cpswapl(from->mode, to->mode); + cpswaps(from->rotation, to->rotation); +} + +static void +SRROutputPropertyNotifyEvent(xRROutputPropertyNotifyEvent *from, + xRROutputPropertyNotifyEvent *to) +{ + to->type = from->type; + to->subCode = from->subCode; + cpswaps(from->sequenceNumber, to->sequenceNumber); + cpswapl(from->window, to->window); + cpswapl(from->output, to->output); + cpswapl(from->atom, to->atom); + cpswapl(from->timestamp, to->timestamp); +} + +static void +SRRNotifyEvent (xEvent *from, + xEvent *to) +{ + switch (from->u.u.detail) { + case RRNotify_CrtcChange: + SRRCrtcChangeNotifyEvent ((xRRCrtcChangeNotifyEvent *) from, + (xRRCrtcChangeNotifyEvent *) to); + break; + case RRNotify_OutputChange: + SRROutputChangeNotifyEvent ((xRROutputChangeNotifyEvent *) from, + (xRROutputChangeNotifyEvent *) to); + break; + case RRNotify_OutputProperty: + SRROutputPropertyNotifyEvent ((xRROutputPropertyNotifyEvent *) from, + (xRROutputPropertyNotifyEvent *) to); + break; + default: + break; + } +} + +static int RRGeneration; + +Bool RRInit (void) +{ + if (RRGeneration != serverGeneration) + { + if (!RRModeInit ()) + return FALSE; + if (!RRCrtcInit ()) + return FALSE; + if (!RROutputInit ()) + return FALSE; + RRGeneration = serverGeneration; + } + return TRUE; +} + +Bool RRScreenInit(ScreenPtr pScreen) +{ + rrScrPrivPtr pScrPriv; + + if (!RRInit ()) + return FALSE; + + pScrPriv = (rrScrPrivPtr) xcalloc (1, sizeof (rrScrPrivRec)); + if (!pScrPriv) + return FALSE; + + SetRRScreen(pScreen, pScrPriv); + + /* + * Calling function best set these function vectors + */ + pScrPriv->rrGetInfo = 0; + pScrPriv->maxWidth = pScrPriv->minWidth = pScreen->width; + pScrPriv->maxHeight = pScrPriv->minHeight = pScreen->height; + + pScrPriv->width = pScreen->width; + pScrPriv->height = pScreen->height; + pScrPriv->mmWidth = pScreen->mmWidth; + pScrPriv->mmHeight = pScreen->mmHeight; +#if RANDR_12_INTERFACE + pScrPriv->rrScreenSetSize = NULL; + pScrPriv->rrCrtcSet = NULL; + pScrPriv->rrCrtcSetGamma = NULL; +#endif +#if RANDR_10_INTERFACE + pScrPriv->rrSetConfig = 0; + pScrPriv->rotations = RR_Rotate_0; + pScrPriv->reqWidth = pScreen->width; + pScrPriv->reqHeight = pScreen->height; + pScrPriv->nSizes = 0; + pScrPriv->pSizes = NULL; + pScrPriv->rotation = RR_Rotate_0; + pScrPriv->rate = 0; + pScrPriv->size = 0; +#endif + + /* + * This value doesn't really matter -- any client must call + * GetScreenInfo before reading it which will automatically update + * the time + */ + pScrPriv->lastSetTime = currentTime; + pScrPriv->lastConfigTime = currentTime; + + wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen); + + pScrPriv->numOutputs = 0; + pScrPriv->outputs = NULL; + pScrPriv->numCrtcs = 0; + pScrPriv->crtcs = NULL; + + RRNScreens += 1; /* keep count of screens that implement randr */ + return TRUE; +} + +/*ARGSUSED*/ +static int +RRFreeClient (pointer data, XID id) +{ + RREventPtr pRREvent; + WindowPtr pWin; + RREventPtr *pHead, pCur, pPrev; + + pRREvent = (RREventPtr) data; + pWin = pRREvent->window; + pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, RREventType); + if (pHead) { + pPrev = 0; + for (pCur = *pHead; pCur && pCur != pRREvent; pCur=pCur->next) + pPrev = pCur; + if (pCur) + { + if (pPrev) + pPrev->next = pRREvent->next; + else + *pHead = pRREvent->next; + } + } + xfree ((pointer) pRREvent); + return 1; +} + +/*ARGSUSED*/ +static int +RRFreeEvents (pointer data, XID id) +{ + RREventPtr *pHead, pCur, pNext; + + pHead = (RREventPtr *) data; + for (pCur = *pHead; pCur; pCur = pNext) { + pNext = pCur->next; + FreeResource (pCur->clientResource, RRClientType); + xfree ((pointer) pCur); + } + xfree ((pointer) pHead); + return 1; +} + +void +RRExtensionInit (void) +{ + ExtensionEntry *extEntry; + + if (RRNScreens == 0) return; + + if (!dixRequestPrivate(RRClientPrivateKey, + sizeof (RRClientRec) + + screenInfo.numScreens * sizeof (RRTimesRec))) + return; + if (!AddCallback (&ClientStateCallback, RRClientCallback, 0)) + return; + + RRClientType = CreateNewResourceType(RRFreeClient); + if (!RRClientType) + return; + RREventType = CreateNewResourceType(RRFreeEvents); + if (!RREventType) + return; + extEntry = AddExtension (RANDR_NAME, RRNumberEvents, RRNumberErrors, + ProcRRDispatch, SProcRRDispatch, + RRResetProc, StandardMinorOpcode); + if (!extEntry) + return; + RRErrorBase = extEntry->errorBase; + RREventBase = extEntry->eventBase; + EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr) + SRRScreenChangeNotifyEvent; + EventSwapVector[RREventBase + RRNotify] = (EventSwapPtr) + SRRNotifyEvent; +#ifdef PANORAMIX + RRXineramaExtensionInit(); +#endif +} + +static int +TellChanged (WindowPtr pWin, pointer value) +{ + RREventPtr *pHead, pRREvent; + ClientPtr client; + ScreenPtr pScreen = pWin->drawable.pScreen; + rrScrPriv(pScreen); + int i; + + pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, RREventType); + if (!pHead) + return WT_WALKCHILDREN; + + for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) + { + client = pRREvent->client; + if (client == serverClient || client->clientGone) + continue; + + if (pRREvent->mask & RRScreenChangeNotifyMask) + RRDeliverScreenEvent (client, pWin, pScreen); + + if (pRREvent->mask & RRCrtcChangeNotifyMask) + { + for (i = 0; i < pScrPriv->numCrtcs; i++) + { + RRCrtcPtr crtc = pScrPriv->crtcs[i]; + if (crtc->changed) + RRDeliverCrtcEvent (client, pWin, crtc); + } + } + + if (pRREvent->mask & RROutputChangeNotifyMask) + { + for (i = 0; i < pScrPriv->numOutputs; i++) + { + RROutputPtr output = pScrPriv->outputs[i]; + if (output->changed) + RRDeliverOutputEvent (client, pWin, output); + } + } + } + return WT_WALKCHILDREN; +} + +/* + * Something changed; send events and adjust pointer position + */ +void +RRTellChanged (ScreenPtr pScreen) +{ + rrScrPriv (pScreen); + int i; + + if (pScrPriv->changed) + { + UpdateCurrentTime (); + if (pScrPriv->configChanged) + { + pScrPriv->lastConfigTime = currentTime; + pScrPriv->configChanged = FALSE; + } + pScrPriv->changed = FALSE; + WalkTree (pScreen, TellChanged, (pointer) pScreen); + 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) + { + pScrPriv->layoutChanged = FALSE; + RRPointerScreenConfigured (pScreen); + RRSendConfigNotify (pScreen); + } + } +} + +/* + * Return the first output which is connected to an active CRTC + * Used in emulating 1.0 behaviour + */ +RROutputPtr +RRFirstOutput (ScreenPtr pScreen) +{ + rrScrPriv(pScreen); + RROutputPtr output; + int i, j; + + for (i = 0; i < pScrPriv->numCrtcs; i++) + { + RRCrtcPtr crtc = pScrPriv->crtcs[i]; + for (j = 0; j < pScrPriv->numOutputs; j++) + { + output = pScrPriv->outputs[j]; + if (output->crtc == crtc) + return output; + } + } + return NULL; +} + +CARD16 +RRVerticalRefresh (xRRModeInfo *mode) +{ + CARD32 refresh; + CARD32 dots = mode->hTotal * mode->vTotal; + if (!dots) + return 0; + refresh = (mode->dotClock + dots/2) / dots; + if (refresh > 0xffff) + refresh = 0xffff; + return (CARD16) refresh; +} + +static int +ProcRRDispatch (ClientPtr client) +{ + REQUEST(xReq); + if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data]) + return BadRequest; + return (*ProcRandrVector[stuff->data]) (client); +} + +static int +SProcRRDispatch (ClientPtr client) +{ + REQUEST(xReq); + if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data]) + return BadRequest; + return (*SProcRandrVector[stuff->data]) (client); +} + diff --git a/programs/Xserver/randr/randr.h b/programs/Xserver/randr/randr.h new file mode 100644 index 0000000..17e6ef9 --- /dev/null +++ b/programs/Xserver/randr/randr.h @@ -0,0 +1,141 @@ +/* + * Copyright © 2000 Compaq Computer Corporation + * Copyright © 2002 Hewlett Packard Company + * Copyright © 2006 Intel Corporation + * + * 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. + * + * Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc. + * Keith Packard, Intel Corporation + */ + +#ifndef _RANDR_H_ +#define _RANDR_H_ + +typedef unsigned short Rotation; +typedef unsigned short SizeID; +typedef unsigned short SubpixelOrder; +typedef unsigned short Connection; +typedef unsigned short XRandrRotation; +typedef unsigned short XRandrSizeID; +typedef unsigned short XRandrSubpixelOrder; +typedef unsigned long XRandrModeFlags; + +#define RANDR_NAME "RANDR" +#define RANDR_MAJOR 1 +#define RANDR_MINOR 2 + +#define RRNumberErrors 3 +#define RRNumberEvents 2 +#define RRNumberRequests 25 + +#define X_RRQueryVersion 0 +/* we skip 1 to make old clients fail pretty immediately */ +#define X_RROldGetScreenInfo 1 +#define X_RR1_0SetScreenConfig 2 +/* V1.0 apps share the same set screen config request id */ +#define X_RRSetScreenConfig 2 +#define X_RROldScreenChangeSelectInput 3 +/* 3 used to be ScreenChangeSelectInput; deprecated */ +#define X_RRSelectInput 4 +#define X_RRGetScreenInfo 5 + +/* V1.2 additions */ +#define X_RRGetScreenSizeRange 6 +#define X_RRSetScreenSize 7 +#define X_RRGetScreenResources 8 +#define X_RRGetOutputInfo 9 +#define X_RRListOutputProperties 10 +#define X_RRQueryOutputProperty 11 +#define X_RRConfigureOutputProperty 12 +#define X_RRChangeOutputProperty 13 +#define X_RRDeleteOutputProperty 14 +#define X_RRGetOutputProperty 15 +#define X_RRCreateMode 16 +#define X_RRDestroyMode 17 +#define X_RRAddOutputMode 18 +#define X_RRDeleteOutputMode 19 +#define X_RRGetCrtcInfo 20 +#define X_RRSetCrtcConfig 21 +#define X_RRGetCrtcGammaSize 22 +#define X_RRGetCrtcGamma 23 +#define X_RRSetCrtcGamma 24 + +/* Event selection bits */ +#define RRScreenChangeNotifyMask (1L << 0) +/* V1.2 additions */ +#define RRCrtcChangeNotifyMask (1L << 1) +#define RROutputChangeNotifyMask (1L << 2) +#define RROutputPropertyNotifyMask (1L << 3) + +/* Event codes */ +#define RRScreenChangeNotify 0 +/* V1.2 additions */ +#define RRNotify 1 +/* RRNotify Subcodes */ +#define RRNotify_CrtcChange 0 +#define RRNotify_OutputChange 1 +#define RRNotify_OutputProperty 2 + +/* used in the rotation field; rotation and reflection in 0.1 proto. */ +#define RR_Rotate_0 1 +#define RR_Rotate_90 2 +#define RR_Rotate_180 4 +#define RR_Rotate_270 8 + +/* new in 1.0 protocol, to allow reflection of screen */ + +#define RR_Reflect_X 16 +#define RR_Reflect_Y 32 + +#define RRSetConfigSuccess 0 +#define RRSetConfigInvalidConfigTime 1 +#define RRSetConfigInvalidTime 2 +#define RRSetConfigFailed 3 + +/* new in 1.2 protocol */ + +#define RR_HSyncPositive 0x00000001 +#define RR_HSyncNegative 0x00000002 +#define RR_VSyncPositive 0x00000004 +#define RR_VSyncNegative 0x00000008 +#define RR_Interlace 0x00000010 +#define RR_DoubleScan 0x00000020 +#define RR_CSync 0x00000040 +#define RR_CSyncPositive 0x00000080 +#define RR_CSyncNegative 0x00000100 +#define RR_HSkewPresent 0x00000200 +#define RR_BCast 0x00000400 +#define RR_PixelMultiplex 0x00000800 +#define RR_DoubleClock 0x00001000 +#define RR_ClockDivideBy2 0x00002000 + +#define RR_Connected 0 +#define RR_Disconnected 1 +#define RR_UnknownConnection 2 + +#define BadRROutput 0 +#define BadRRCrtc 1 +#define BadRRMode 2 + +/* Conventional RandR output properties */ + +#define RR_PROPERTY_RANDR_EDID "RANDR_EDID" + +#endif /* _RANDR_H_ */ diff --git a/programs/Xserver/randr/randr.h.NX.original b/programs/Xserver/randr/randr.h.NX.original new file mode 100644 index 0000000..17e6ef9 --- /dev/null +++ b/programs/Xserver/randr/randr.h.NX.original @@ -0,0 +1,141 @@ +/* + * Copyright © 2000 Compaq Computer Corporation + * Copyright © 2002 Hewlett Packard Company + * Copyright © 2006 Intel Corporation + * + * 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. + * + * Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc. + * Keith Packard, Intel Corporation + */ + +#ifndef _RANDR_H_ +#define _RANDR_H_ + +typedef unsigned short Rotation; +typedef unsigned short SizeID; +typedef unsigned short SubpixelOrder; +typedef unsigned short Connection; +typedef unsigned short XRandrRotation; +typedef unsigned short XRandrSizeID; +typedef unsigned short XRandrSubpixelOrder; +typedef unsigned long XRandrModeFlags; + +#define RANDR_NAME "RANDR" +#define RANDR_MAJOR 1 +#define RANDR_MINOR 2 + +#define RRNumberErrors 3 +#define RRNumberEvents 2 +#define RRNumberRequests 25 + +#define X_RRQueryVersion 0 +/* we skip 1 to make old clients fail pretty immediately */ +#define X_RROldGetScreenInfo 1 +#define X_RR1_0SetScreenConfig 2 +/* V1.0 apps share the same set screen config request id */ +#define X_RRSetScreenConfig 2 +#define X_RROldScreenChangeSelectInput 3 +/* 3 used to be ScreenChangeSelectInput; deprecated */ +#define X_RRSelectInput 4 +#define X_RRGetScreenInfo 5 + +/* V1.2 additions */ +#define X_RRGetScreenSizeRange 6 +#define X_RRSetScreenSize 7 +#define X_RRGetScreenResources 8 +#define X_RRGetOutputInfo 9 +#define X_RRListOutputProperties 10 +#define X_RRQueryOutputProperty 11 +#define X_RRConfigureOutputProperty 12 +#define X_RRChangeOutputProperty 13 +#define X_RRDeleteOutputProperty 14 +#define X_RRGetOutputProperty 15 +#define X_RRCreateMode 16 +#define X_RRDestroyMode 17 +#define X_RRAddOutputMode 18 +#define X_RRDeleteOutputMode 19 +#define X_RRGetCrtcInfo 20 +#define X_RRSetCrtcConfig 21 +#define X_RRGetCrtcGammaSize 22 +#define X_RRGetCrtcGamma 23 +#define X_RRSetCrtcGamma 24 + +/* Event selection bits */ +#define RRScreenChangeNotifyMask (1L << 0) +/* V1.2 additions */ +#define RRCrtcChangeNotifyMask (1L << 1) +#define RROutputChangeNotifyMask (1L << 2) +#define RROutputPropertyNotifyMask (1L << 3) + +/* Event codes */ +#define RRScreenChangeNotify 0 +/* V1.2 additions */ +#define RRNotify 1 +/* RRNotify Subcodes */ +#define RRNotify_CrtcChange 0 +#define RRNotify_OutputChange 1 +#define RRNotify_OutputProperty 2 + +/* used in the rotation field; rotation and reflection in 0.1 proto. */ +#define RR_Rotate_0 1 +#define RR_Rotate_90 2 +#define RR_Rotate_180 4 +#define RR_Rotate_270 8 + +/* new in 1.0 protocol, to allow reflection of screen */ + +#define RR_Reflect_X 16 +#define RR_Reflect_Y 32 + +#define RRSetConfigSuccess 0 +#define RRSetConfigInvalidConfigTime 1 +#define RRSetConfigInvalidTime 2 +#define RRSetConfigFailed 3 + +/* new in 1.2 protocol */ + +#define RR_HSyncPositive 0x00000001 +#define RR_HSyncNegative 0x00000002 +#define RR_VSyncPositive 0x00000004 +#define RR_VSyncNegative 0x00000008 +#define RR_Interlace 0x00000010 +#define RR_DoubleScan 0x00000020 +#define RR_CSync 0x00000040 +#define RR_CSyncPositive 0x00000080 +#define RR_CSyncNegative 0x00000100 +#define RR_HSkewPresent 0x00000200 +#define RR_BCast 0x00000400 +#define RR_PixelMultiplex 0x00000800 +#define RR_DoubleClock 0x00001000 +#define RR_ClockDivideBy2 0x00002000 + +#define RR_Connected 0 +#define RR_Disconnected 1 +#define RR_UnknownConnection 2 + +#define BadRROutput 0 +#define BadRRCrtc 1 +#define BadRRMode 2 + +/* Conventional RandR output properties */ + +#define RR_PROPERTY_RANDR_EDID "RANDR_EDID" + +#endif /* _RANDR_H_ */ diff --git a/CHANGELOG.X.original b/programs/Xserver/randr/randr.h.X.original similarity index 100% copy from CHANGELOG.X.original copy to programs/Xserver/randr/randr.h.X.original diff --git a/programs/Xserver/randr/randrproto.h b/programs/Xserver/randr/randrproto.h new file mode 100644 index 0000000..7d5c139 --- /dev/null +++ b/programs/Xserver/randr/randrproto.h @@ -0,0 +1,655 @@ +/* + * Copyright © 2000 Compaq Computer Corporation + * Copyright © 2002 Hewlett-Packard Company + * Copyright © 2006 Intel Corporation + * + * 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. + * + * Author: Jim Gettys, Hewlett-Packard Company, Inc. + * Keith Packard, Intel Corporation + */ + +/* note that RANDR 1.0 is incompatible with version 0.0, or 0.1 */ +/* V1.0 removes depth switching from the protocol */ +#ifndef _XRANDRP_H_ +#define _XRANDRP_H_ + +/*#include <X11/extensions/randr.h>*/ +#include "randr.h" + +#define Window CARD32 +#define Drawable CARD32 +#define Font CARD32 +#define Pixmap CARD32 +#define Cursor CARD32 +#define Colormap CARD32 +#define GContext CARD32 +#define Atom CARD32 +#define Time CARD32 +#define KeyCode CARD8 +#define KeySym CARD32 +#define RROutput CARD32 +#define RRMode CARD32 +#define RRCrtc CARD32 +#define RRModeFlags CARD32 + +#define Rotation CARD16 +#define SizeID CARD16 +#define SubpixelOrder CARD16 + +/* + * data structures + */ + +typedef struct { + CARD16 widthInPixels B16; + CARD16 heightInPixels B16; + CARD16 widthInMillimeters B16; + CARD16 heightInMillimeters B16; +} xScreenSizes; +#define sz_xScreenSizes 8 + +/* + * requests and replies + */ + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + CARD32 majorVersion B32; + CARD32 minorVersion B32; +} xRRQueryVersionReq; +#define sz_xRRQueryVersionReq 12 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 majorVersion B32; + CARD32 minorVersion B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xRRQueryVersionReply; +#define sz_xRRQueryVersionReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + Window window B32; +} xRRGetScreenInfoReq; +#define sz_xRRGetScreenInfoReq 8 + +/* + * the xRRScreenInfoReply structure is followed by: + * + * the size information + */ + + +typedef struct { + BYTE type; /* X_Reply */ + BYTE setOfRotations; + CARD16 sequenceNumber B16; + CARD32 length B32; + Window root B32; + Time timestamp B32; + Time configTimestamp B32; + CARD16 nSizes B16; + SizeID sizeID B16; + Rotation rotation B16; + CARD16 rate B16; + CARD16 nrateEnts B16; + CARD16 pad B16; +} xRRGetScreenInfoReply; +#define sz_xRRGetScreenInfoReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + Drawable drawable B32; + Time timestamp B32; + Time configTimestamp B32; + SizeID sizeID B16; + Rotation rotation B16; +} xRR1_0SetScreenConfigReq; +#define sz_xRR1_0SetScreenConfigReq 20 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + Drawable drawable B32; + Time timestamp B32; + Time configTimestamp B32; + SizeID sizeID B16; + Rotation rotation B16; + CARD16 rate B16; + CARD16 pad B16; +} xRRSetScreenConfigReq; +#define sz_xRRSetScreenConfigReq 24 + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 status; + CARD16 sequenceNumber B16; + CARD32 length B32; + Time newTimestamp B32; + Time newConfigTimestamp B32; + Window root; + CARD16 subpixelOrder B16; + CARD16 pad4 B16; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xRRSetScreenConfigReply; +#define sz_xRRSetScreenConfigReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + Window window B32; + CARD16 enable B16; + CARD16 pad2 B16; +} xRRSelectInputReq; +#define sz_xRRSelectInputReq 12 + +/* + * Additions for version 1.2 + */ + +typedef struct _xRRModeInfo { + RRMode id B32; + CARD16 width B16; + CARD16 height B16; + CARD32 dotClock B32; + CARD16 hSyncStart B16; + CARD16 hSyncEnd B16; + CARD16 hTotal B16; + CARD16 hSkew B16; + CARD16 vSyncStart B16; + CARD16 vSyncEnd B16; + CARD16 vTotal B16; + CARD16 nameLength B16; + RRModeFlags modeFlags B32; +} xRRModeInfo; +#define sz_xRRModeInfo 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + Window window B32; +} xRRGetScreenSizeRangeReq; +#define sz_xRRGetScreenSizeRangeReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 pad; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 minWidth B16; + CARD16 minHeight B16; + CARD16 maxWidth B16; + CARD16 maxHeight B16; + CARD32 pad0 B32; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; +} xRRGetScreenSizeRangeReply; +#define sz_xRRGetScreenSizeRangeReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + Window window B32; + CARD16 width B16; + CARD16 height B16; + CARD32 widthInMillimeters B32; + CARD32 heightInMillimeters B32; +} xRRSetScreenSizeReq; +#define sz_xRRSetScreenSizeReq 20 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + Window window B32; +} xRRGetScreenResourcesReq; +#define sz_xRRGetScreenResourcesReq 8 + +typedef struct { + BYTE type; + CARD8 pad; + CARD16 sequenceNumber B16; + CARD32 length B32; + Time timestamp B32; + Time configTimestamp B32; + CARD16 nCrtcs B16; + CARD16 nOutputs B16; + CARD16 nModes B16; + CARD16 nbytesNames B16; + CARD32 pad1 B32; + CARD32 pad2 B32; +} xRRGetScreenResourcesReply; +#define sz_xRRGetScreenResourcesReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RROutput output B32; + Time configTimestamp B32; +} xRRGetOutputInfoReq; +#define sz_xRRGetOutputInfoReq 12 + +typedef struct { + BYTE type; + CARD8 status; + CARD16 sequenceNumber B16; + CARD32 length B32; + Time timestamp B32; + RRCrtc crtc B32; + CARD32 mmWidth B32; + CARD32 mmHeight B32; + CARD8 connection; + CARD8 subpixelOrder; + CARD16 nCrtcs B16; + CARD16 nModes B16; + CARD16 nPreferred B16; + CARD16 nClones B16; + CARD16 nameLength B16; +} xRRGetOutputInfoReply; +#define sz_xRRGetOutputInfoReply 36 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RROutput output B32; +} xRRListOutputPropertiesReq; +#define sz_xRRListOutputPropertiesReq 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; +} xRRListOutputPropertiesReply; +#define sz_xRRListOutputPropertiesReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RROutput output B32; + Atom property B32; +} xRRQueryOutputPropertyReq; +#define sz_xRRQueryOutputPropertyReq 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; +} xRRQueryOutputPropertyReply; +#define sz_xRRQueryOutputPropertyReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RROutput output B32; + Atom property B32; + BOOL pending; + BOOL range; + CARD16 pad B16; +} xRRConfigureOutputPropertyReq; +#define sz_xRRConfigureOutputPropertyReq 16 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RROutput output B32; + Atom property B32; + Atom type B32; + CARD8 format; + CARD8 mode; + CARD16 pad; + CARD32 nUnits B32; +} xRRChangeOutputPropertyReq; +#define sz_xRRChangeOutputPropertyReq 24 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RROutput output B32; + Atom property B32; +} xRRDeleteOutputPropertyReq; +#define sz_xRRDeleteOutputPropertyReq 12 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RROutput output 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; +} xRRGetOutputPropertyReq; +#define sz_xRRGetOutputPropertyReq 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; +} xRRGetOutputPropertyReply; +#define sz_xRRGetOutputPropertyReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + Window window B32; + xRRModeInfo modeInfo; +} xRRCreateModeReq; +#define sz_xRRCreateModeReq 40 + +typedef struct { + BYTE type; + CARD8 pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + RRMode mode B32; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xRRCreateModeReply; +#define sz_xRRCreateModeReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RRMode mode B32; +} xRRDestroyModeReq; +#define sz_xRRDestroyModeReq 8 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RROutput output B32; + RRMode mode B32; +} xRRAddOutputModeReq; +#define sz_xRRAddOutputModeReq 12 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RROutput output B32; + RRMode mode B32; +} xRRDeleteOutputModeReq; +#define sz_xRRDeleteOutputModeReq 12 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RRCrtc crtc B32; + Time configTimestamp B32; +} xRRGetCrtcInfoReq; +#define sz_xRRGetCrtcInfoReq 12 + +typedef struct { + BYTE type; + CARD8 status; + CARD16 sequenceNumber B16; + CARD32 length B32; + Time timestamp B32; + INT16 x B16; + INT16 y B16; + CARD16 width B16; + CARD16 height B16; + RRMode mode B32; + Rotation rotation B16; + Rotation rotations B16; + CARD16 nOutput B16; + CARD16 nPossibleOutput B16; +} xRRGetCrtcInfoReply; +#define sz_xRRGetCrtcInfoReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RRCrtc crtc B32; + Time timestamp B32; + Time configTimestamp B32; + INT16 x B16; + INT16 y B16; + RRMode mode B32; + Rotation rotation B16; + CARD16 pad B16; +} xRRSetCrtcConfigReq; +#define sz_xRRSetCrtcConfigReq 28 + +typedef struct { + BYTE type; + CARD8 status; + CARD16 sequenceNumber B16; + CARD32 length B32; + Time newTimestamp B32; + CARD32 pad1 B32; + CARD32 pad2 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xRRSetCrtcConfigReply; +#define sz_xRRSetCrtcConfigReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RRCrtc crtc B32; +} xRRGetCrtcGammaSizeReq; +#define sz_xRRGetCrtcGammaSizeReq 8 + +typedef struct { + BYTE type; + CARD8 status; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 size B16; + CARD16 pad1 B16; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xRRGetCrtcGammaSizeReply; +#define sz_xRRGetCrtcGammaSizeReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RRCrtc crtc B32; +} xRRGetCrtcGammaReq; +#define sz_xRRGetCrtcGammaReq 8 + +typedef struct { + BYTE type; + CARD8 status; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 size B16; + CARD16 pad1 B16; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xRRGetCrtcGammaReply; +#define sz_xRRGetCrtcGammaReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RRCrtc crtc B32; + CARD16 size B16; + CARD16 pad1 B16; +} xRRSetCrtcGammaReq; +#define sz_xRRSetCrtcGammaReq 12 + +/* + * event + */ +typedef struct { + CARD8 type; /* always evBase + ScreenChangeNotify */ + CARD8 rotation; /* new rotation */ + CARD16 sequenceNumber B16; + Time timestamp B32; /* time screen was changed */ + Time configTimestamp B32; /* time config data was changed */ + Window root B32; /* root window */ + Window window B32; /* window requesting notification */ + SizeID sizeID B16; /* new size ID */ + CARD16 subpixelOrder B16; /* subpixel order */ + CARD16 widthInPixels B16; /* new size */ + CARD16 heightInPixels B16; + CARD16 widthInMillimeters B16; + CARD16 heightInMillimeters B16; +} xRRScreenChangeNotifyEvent; +#define sz_xRRScreenChangeNotifyEvent 32 + +typedef struct { + CARD8 type; /* always evBase + RRNotify */ + CARD8 subCode; /* RRNotify_CrtcChange */ + CARD16 sequenceNumber B16; + Time timestamp B32; /* time crtc was changed */ + Window window B32; /* window requesting notification */ + RRCrtc crtc B32; /* affected CRTC */ + RRMode mode B32; /* current mode */ + CARD16 rotation B16; /* rotation and reflection */ + CARD16 pad1 B16; /* unused */ + INT16 x B16; /* new location */ + INT16 y B16; + CARD16 width B16; /* new size */ + CARD16 height B16; +} xRRCrtcChangeNotifyEvent; +#define sz_xRRCrtcChangeNotifyEvent 32 + +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 */ + Window window B32; /* window requesting notification */ + RROutput output B32; /* affected output */ + RRCrtc crtc B32; /* current crtc */ + RRMode mode B32; /* current mode */ + CARD16 rotation B16; /* rotation and reflection */ + CARD8 connection; /* connection status */ + CARD8 subpixelOrder; /* subpixel order */ +} xRROutputChangeNotifyEvent; +#define sz_xRROutputChangeNotifyEvent 32 + +typedef struct { + CARD8 type; /* always evBase + RRNotify */ + CARD8 subCode; /* RRNotify_OutputProperty */ + CARD16 sequenceNumber B16; + Window window B32; /* window requesting notification */ + RROutput output B32; /* affected output */ + Atom atom B32; /* property name */ + Time timestamp B32; /* time crtc was changed */ + CARD8 state; /* NewValue or Deleted */ + CARD8 pad1; + CARD16 pad2 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; +} xRROutputPropertyNotifyEvent; +#define sz_xRROutputPropertyNotifyEvent 32 + +#undef RRModeFlags +#undef RRCrtc +#undef RRMode +#undef RROutput +#undef RRMode +#undef RRCrtc +#undef Drawable +#undef Window +#undef Font +#undef Pixmap +#undef Cursor +#undef Colormap +#undef GContext +#undef Atom +#undef Time +#undef KeyCode +#undef KeySym +#undef Rotation +#undef SizeID +#undef SubpixelOrder + +#endif /* _XRANDRP_H_ */ diff --git a/programs/Xserver/randr/randrproto.h.NX.original b/programs/Xserver/randr/randrproto.h.NX.original new file mode 100644 index 0000000..7d5c139 --- /dev/null +++ b/programs/Xserver/randr/randrproto.h.NX.original @@ -0,0 +1,655 @@ +/* + * Copyright © 2000 Compaq Computer Corporation + * Copyright © 2002 Hewlett-Packard Company + * Copyright © 2006 Intel Corporation + * + * 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. + * + * Author: Jim Gettys, Hewlett-Packard Company, Inc. + * Keith Packard, Intel Corporation + */ + +/* note that RANDR 1.0 is incompatible with version 0.0, or 0.1 */ +/* V1.0 removes depth switching from the protocol */ +#ifndef _XRANDRP_H_ +#define _XRANDRP_H_ + +/*#include <X11/extensions/randr.h>*/ +#include "randr.h" + +#define Window CARD32 +#define Drawable CARD32 +#define Font CARD32 +#define Pixmap CARD32 +#define Cursor CARD32 +#define Colormap CARD32 +#define GContext CARD32 +#define Atom CARD32 +#define Time CARD32 +#define KeyCode CARD8 +#define KeySym CARD32 +#define RROutput CARD32 +#define RRMode CARD32 +#define RRCrtc CARD32 +#define RRModeFlags CARD32 + +#define Rotation CARD16 +#define SizeID CARD16 +#define SubpixelOrder CARD16 + +/* + * data structures + */ + +typedef struct { + CARD16 widthInPixels B16; + CARD16 heightInPixels B16; + CARD16 widthInMillimeters B16; + CARD16 heightInMillimeters B16; +} xScreenSizes; +#define sz_xScreenSizes 8 + +/* + * requests and replies + */ + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + CARD32 majorVersion B32; + CARD32 minorVersion B32; +} xRRQueryVersionReq; +#define sz_xRRQueryVersionReq 12 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 majorVersion B32; + CARD32 minorVersion B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xRRQueryVersionReply; +#define sz_xRRQueryVersionReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + Window window B32; +} xRRGetScreenInfoReq; +#define sz_xRRGetScreenInfoReq 8 + +/* + * the xRRScreenInfoReply structure is followed by: + * + * the size information + */ + + +typedef struct { + BYTE type; /* X_Reply */ + BYTE setOfRotations; + CARD16 sequenceNumber B16; + CARD32 length B32; + Window root B32; + Time timestamp B32; + Time configTimestamp B32; + CARD16 nSizes B16; + SizeID sizeID B16; + Rotation rotation B16; + CARD16 rate B16; + CARD16 nrateEnts B16; + CARD16 pad B16; +} xRRGetScreenInfoReply; +#define sz_xRRGetScreenInfoReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + Drawable drawable B32; + Time timestamp B32; + Time configTimestamp B32; + SizeID sizeID B16; + Rotation rotation B16; +} xRR1_0SetScreenConfigReq; +#define sz_xRR1_0SetScreenConfigReq 20 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + Drawable drawable B32; + Time timestamp B32; + Time configTimestamp B32; + SizeID sizeID B16; + Rotation rotation B16; + CARD16 rate B16; + CARD16 pad B16; +} xRRSetScreenConfigReq; +#define sz_xRRSetScreenConfigReq 24 + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 status; + CARD16 sequenceNumber B16; + CARD32 length B32; + Time newTimestamp B32; + Time newConfigTimestamp B32; + Window root; + CARD16 subpixelOrder B16; + CARD16 pad4 B16; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xRRSetScreenConfigReply; +#define sz_xRRSetScreenConfigReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + Window window B32; + CARD16 enable B16; + CARD16 pad2 B16; +} xRRSelectInputReq; +#define sz_xRRSelectInputReq 12 + +/* + * Additions for version 1.2 + */ + +typedef struct _xRRModeInfo { + RRMode id B32; + CARD16 width B16; + CARD16 height B16; + CARD32 dotClock B32; + CARD16 hSyncStart B16; + CARD16 hSyncEnd B16; + CARD16 hTotal B16; + CARD16 hSkew B16; + CARD16 vSyncStart B16; + CARD16 vSyncEnd B16; + CARD16 vTotal B16; + CARD16 nameLength B16; + RRModeFlags modeFlags B32; +} xRRModeInfo; +#define sz_xRRModeInfo 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + Window window B32; +} xRRGetScreenSizeRangeReq; +#define sz_xRRGetScreenSizeRangeReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 pad; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 minWidth B16; + CARD16 minHeight B16; + CARD16 maxWidth B16; + CARD16 maxHeight B16; + CARD32 pad0 B32; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; +} xRRGetScreenSizeRangeReply; +#define sz_xRRGetScreenSizeRangeReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + Window window B32; + CARD16 width B16; + CARD16 height B16; + CARD32 widthInMillimeters B32; + CARD32 heightInMillimeters B32; +} xRRSetScreenSizeReq; +#define sz_xRRSetScreenSizeReq 20 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + Window window B32; +} xRRGetScreenResourcesReq; +#define sz_xRRGetScreenResourcesReq 8 + +typedef struct { + BYTE type; + CARD8 pad; + CARD16 sequenceNumber B16; + CARD32 length B32; + Time timestamp B32; + Time configTimestamp B32; + CARD16 nCrtcs B16; + CARD16 nOutputs B16; + CARD16 nModes B16; + CARD16 nbytesNames B16; + CARD32 pad1 B32; + CARD32 pad2 B32; +} xRRGetScreenResourcesReply; +#define sz_xRRGetScreenResourcesReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RROutput output B32; + Time configTimestamp B32; +} xRRGetOutputInfoReq; +#define sz_xRRGetOutputInfoReq 12 + +typedef struct { + BYTE type; + CARD8 status; + CARD16 sequenceNumber B16; + CARD32 length B32; + Time timestamp B32; + RRCrtc crtc B32; + CARD32 mmWidth B32; + CARD32 mmHeight B32; + CARD8 connection; + CARD8 subpixelOrder; + CARD16 nCrtcs B16; + CARD16 nModes B16; + CARD16 nPreferred B16; + CARD16 nClones B16; + CARD16 nameLength B16; +} xRRGetOutputInfoReply; +#define sz_xRRGetOutputInfoReply 36 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RROutput output B32; +} xRRListOutputPropertiesReq; +#define sz_xRRListOutputPropertiesReq 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; +} xRRListOutputPropertiesReply; +#define sz_xRRListOutputPropertiesReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RROutput output B32; + Atom property B32; +} xRRQueryOutputPropertyReq; +#define sz_xRRQueryOutputPropertyReq 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; +} xRRQueryOutputPropertyReply; +#define sz_xRRQueryOutputPropertyReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RROutput output B32; + Atom property B32; + BOOL pending; + BOOL range; + CARD16 pad B16; +} xRRConfigureOutputPropertyReq; +#define sz_xRRConfigureOutputPropertyReq 16 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RROutput output B32; + Atom property B32; + Atom type B32; + CARD8 format; + CARD8 mode; + CARD16 pad; + CARD32 nUnits B32; +} xRRChangeOutputPropertyReq; +#define sz_xRRChangeOutputPropertyReq 24 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RROutput output B32; + Atom property B32; +} xRRDeleteOutputPropertyReq; +#define sz_xRRDeleteOutputPropertyReq 12 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RROutput output 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; +} xRRGetOutputPropertyReq; +#define sz_xRRGetOutputPropertyReq 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; +} xRRGetOutputPropertyReply; +#define sz_xRRGetOutputPropertyReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + Window window B32; + xRRModeInfo modeInfo; +} xRRCreateModeReq; +#define sz_xRRCreateModeReq 40 + +typedef struct { + BYTE type; + CARD8 pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + RRMode mode B32; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xRRCreateModeReply; +#define sz_xRRCreateModeReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RRMode mode B32; +} xRRDestroyModeReq; +#define sz_xRRDestroyModeReq 8 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RROutput output B32; + RRMode mode B32; +} xRRAddOutputModeReq; +#define sz_xRRAddOutputModeReq 12 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RROutput output B32; + RRMode mode B32; +} xRRDeleteOutputModeReq; +#define sz_xRRDeleteOutputModeReq 12 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RRCrtc crtc B32; + Time configTimestamp B32; +} xRRGetCrtcInfoReq; +#define sz_xRRGetCrtcInfoReq 12 + +typedef struct { + BYTE type; + CARD8 status; + CARD16 sequenceNumber B16; + CARD32 length B32; + Time timestamp B32; + INT16 x B16; + INT16 y B16; + CARD16 width B16; + CARD16 height B16; + RRMode mode B32; + Rotation rotation B16; + Rotation rotations B16; + CARD16 nOutput B16; + CARD16 nPossibleOutput B16; +} xRRGetCrtcInfoReply; +#define sz_xRRGetCrtcInfoReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RRCrtc crtc B32; + Time timestamp B32; + Time configTimestamp B32; + INT16 x B16; + INT16 y B16; + RRMode mode B32; + Rotation rotation B16; + CARD16 pad B16; +} xRRSetCrtcConfigReq; +#define sz_xRRSetCrtcConfigReq 28 + +typedef struct { + BYTE type; + CARD8 status; + CARD16 sequenceNumber B16; + CARD32 length B32; + Time newTimestamp B32; + CARD32 pad1 B32; + CARD32 pad2 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xRRSetCrtcConfigReply; +#define sz_xRRSetCrtcConfigReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RRCrtc crtc B32; +} xRRGetCrtcGammaSizeReq; +#define sz_xRRGetCrtcGammaSizeReq 8 + +typedef struct { + BYTE type; + CARD8 status; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 size B16; + CARD16 pad1 B16; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xRRGetCrtcGammaSizeReply; +#define sz_xRRGetCrtcGammaSizeReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RRCrtc crtc B32; +} xRRGetCrtcGammaReq; +#define sz_xRRGetCrtcGammaReq 8 + +typedef struct { + BYTE type; + CARD8 status; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 size B16; + CARD16 pad1 B16; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xRRGetCrtcGammaReply; +#define sz_xRRGetCrtcGammaReply 32 + +typedef struct { + CARD8 reqType; + CARD8 randrReqType; + CARD16 length B16; + RRCrtc crtc B32; + CARD16 size B16; + CARD16 pad1 B16; +} xRRSetCrtcGammaReq; +#define sz_xRRSetCrtcGammaReq 12 + +/* + * event + */ +typedef struct { + CARD8 type; /* always evBase + ScreenChangeNotify */ + CARD8 rotation; /* new rotation */ + CARD16 sequenceNumber B16; + Time timestamp B32; /* time screen was changed */ + Time configTimestamp B32; /* time config data was changed */ + Window root B32; /* root window */ + Window window B32; /* window requesting notification */ + SizeID sizeID B16; /* new size ID */ + CARD16 subpixelOrder B16; /* subpixel order */ + CARD16 widthInPixels B16; /* new size */ + CARD16 heightInPixels B16; + CARD16 widthInMillimeters B16; + CARD16 heightInMillimeters B16; +} xRRScreenChangeNotifyEvent; +#define sz_xRRScreenChangeNotifyEvent 32 + +typedef struct { + CARD8 type; /* always evBase + RRNotify */ + CARD8 subCode; /* RRNotify_CrtcChange */ + CARD16 sequenceNumber B16; + Time timestamp B32; /* time crtc was changed */ + Window window B32; /* window requesting notification */ + RRCrtc crtc B32; /* affected CRTC */ + RRMode mode B32; /* current mode */ + CARD16 rotation B16; /* rotation and reflection */ + CARD16 pad1 B16; /* unused */ + INT16 x B16; /* new location */ + INT16 y B16; + CARD16 width B16; /* new size */ + CARD16 height B16; +} xRRCrtcChangeNotifyEvent; +#define sz_xRRCrtcChangeNotifyEvent 32 + +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 */ + Window window B32; /* window requesting notification */ + RROutput output B32; /* affected output */ + RRCrtc crtc B32; /* current crtc */ + RRMode mode B32; /* current mode */ + CARD16 rotation B16; /* rotation and reflection */ + CARD8 connection; /* connection status */ + CARD8 subpixelOrder; /* subpixel order */ +} xRROutputChangeNotifyEvent; +#define sz_xRROutputChangeNotifyEvent 32 + +typedef struct { + CARD8 type; /* always evBase + RRNotify */ + CARD8 subCode; /* RRNotify_OutputProperty */ + CARD16 sequenceNumber B16; + Window window B32; /* window requesting notification */ + RROutput output B32; /* affected output */ + Atom atom B32; /* property name */ + Time timestamp B32; /* time crtc was changed */ + CARD8 state; /* NewValue or Deleted */ + CARD8 pad1; + CARD16 pad2 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; +} xRROutputPropertyNotifyEvent; +#define sz_xRROutputPropertyNotifyEvent 32 + +#undef RRModeFlags +#undef RRCrtc +#undef RRMode +#undef RROutput +#undef RRMode +#undef RRCrtc +#undef Drawable +#undef Window +#undef Font +#undef Pixmap +#undef Cursor +#undef Colormap +#undef GContext +#undef Atom +#undef Time +#undef KeyCode +#undef KeySym +#undef Rotation +#undef SizeID +#undef SubpixelOrder + +#endif /* _XRANDRP_H_ */ diff --git a/CHANGELOG.X.original b/programs/Xserver/randr/randrproto.h.X.original similarity index 100% copy from CHANGELOG.X.original copy to programs/Xserver/randr/randrproto.h.X.original diff --git a/programs/Xserver/randr/randrstr.h b/programs/Xserver/randr/randrstr.h index cd4ce38..52067b5 100644 --- a/programs/Xserver/randr/randrstr.h +++ b/programs/Xserver/randr/randrstr.h @@ -1,25 +1,28 @@ /* - * $XFree86: xc/programs/Xserver/randr/randrstr.h,v 1.5 2002/09/29 23:39:45 keithp Exp $ - * * Copyright © 2000 Compaq Computer Corporation + * Copyright © 2002 Hewlett-Packard Company + * Copyright © 2006 Intel Corporation * * 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 Compaq not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Compaq makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. + * 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. * - * COMPAQ DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL COMPAQ BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * 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. + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + * + * Author: Jim Gettys, Hewlett-Packard Company, Inc. + * Keith Packard, Intel Corporation */ #ifdef HAVE_DIX_CONFIG_H @@ -29,68 +32,456 @@ #ifndef _RANDRSTR_H_ #define _RANDRSTR_H_ +#include <X11/X.h> +#include <X11/Xproto.h> +#include "misc.h" +#include "os.h" +#include "dixstruct.h" +#include "resource.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "extnsionst.h" +#include "servermd.h" +#ifndef NXAGENT_SERVER #include <X11/extensions/randr.h> +#include <X11/extensions/randrproto.h> +#else +#include "randr.h" +#include "randrproto.h" +#endif +#ifdef RENDER +#include <X11/extensions/render.h> /* we share subpixel order information */ +#include "picturestr.h" +#endif +#include <X11/Xfuncproto.h> + +/* required for ABI compatibility for now */ +#define RANDR_10_INTERFACE 1 +#define RANDR_12_INTERFACE 1 + +typedef XID RRMode; +typedef XID RROutput; +typedef XID RRCrtc; + +extern int RREventBase, RRErrorBase; + +extern int (*ProcRandrVector[RRNumberRequests])(ClientPtr); +extern int (*SProcRandrVector[RRNumberRequests])(ClientPtr); + +/* + * Modeline for a monitor. Name follows directly after this struct + */ + +#define RRModeName(pMode) ((char *) (pMode + 1)) +typedef struct _rrMode RRModeRec, *RRModePtr; +typedef struct _rrPropertyValue RRPropertyValueRec, *RRPropertyValuePtr; +typedef struct _rrProperty RRPropertyRec, *RRPropertyPtr; +typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr; +typedef struct _rrOutput RROutputRec, *RROutputPtr; + +struct _rrMode { + int refcnt; + xRRModeInfo mode; + char *name; + ScreenPtr userScreen; +}; + +struct _rrPropertyValue { + Atom type; /* ignored by server */ + short format; /* format of data for swapping - 8,16,32 */ + long size; /* size of data in (format/8) bytes */ + pointer data; /* private to client */ +}; + +struct _rrProperty { + RRPropertyPtr next; + ATOM propertyName; + Bool is_pending; + Bool range; + Bool immutable; + int num_valid; + INT32 *valid_values; + RRPropertyValueRec current, pending; +}; + +struct _rrCrtc { + RRCrtc id; + ScreenPtr pScreen; + RRModePtr mode; + int x, y; + Rotation rotation; + Rotation rotations; + Bool changed; + int numOutputs; + RROutputPtr *outputs; + int gammaSize; + CARD16 *gammaRed; + CARD16 *gammaBlue; + CARD16 *gammaGreen; + void *devPrivate; +}; + +struct _rrOutput { + RROutput id; + ScreenPtr pScreen; + char *name; + int nameLength; + CARD8 connection; + CARD8 subpixelOrder; + int mmWidth; + int mmHeight; + RRCrtcPtr crtc; + int numCrtcs; + RRCrtcPtr *crtcs; + int numClones; + RROutputPtr *clones; + int numModes; + int numPreferred; + RRModePtr *modes; + int numUserModes; + RRModePtr *userModes; + Bool changed; + RRPropertyPtr properties; + Bool pendingProperties; + void *devPrivate; +}; + +#if RANDR_12_INTERFACE +typedef Bool (*RRScreenSetSizeProcPtr) (ScreenPtr pScreen, + CARD16 width, + CARD16 height, + CARD32 mmWidth, + CARD32 mmHeight); + +typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr pScreen, + RRCrtcPtr crtc, + RRModePtr mode, + int x, + int y, + Rotation rotation, + int numOutputs, + RROutputPtr *outputs); + +typedef Bool (*RRCrtcSetGammaProcPtr) (ScreenPtr pScreen, + RRCrtcPtr crtc); -typedef struct _rrScreenRate { - int rate; - Bool referenced; - Bool oldReferenced; +typedef Bool (*RROutputSetPropertyProcPtr) (ScreenPtr pScreen, + RROutputPtr output, + Atom property, + RRPropertyValuePtr value); + +typedef Bool (*RROutputValidateModeProcPtr) (ScreenPtr pScreen, + RROutputPtr output, + RRModePtr mode); + +typedef void (*RRModeDestroyProcPtr) (ScreenPtr pScreen, + RRModePtr mode); + +#endif + +typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation *rotations); +typedef Bool (*RRCloseScreenProcPtr) ( int i, ScreenPtr pscreen); + +/* These are for 1.0 compatibility */ + +typedef struct _rrRefresh { + CARD16 rate; + RRModePtr mode; } RRScreenRate, *RRScreenRatePtr; typedef struct _rrScreenSize { int id; short width, height; short mmWidth, mmHeight; - RRScreenRatePtr pRates; int nRates; - int nRatesInUse; - Bool referenced; - Bool oldReferenced; + RRScreenRatePtr pRates; } RRScreenSize, *RRScreenSizePtr; +#ifdef RANDR_10_INTERFACE + typedef Bool (*RRSetConfigProcPtr) (ScreenPtr pScreen, Rotation rotation, int rate, RRScreenSizePtr pSize); -typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation *rotations); -typedef Bool (*RRCloseScreenProcPtr) ( int i, ScreenPtr pscreen); +#endif + typedef struct _rrScrPriv { + /* + * 'public' part of the structure; DDXen fill this in + * as they initialize + */ +#if RANDR_10_INTERFACE RRSetConfigProcPtr rrSetConfig; +#endif RRGetInfoProcPtr rrGetInfo; +#if RANDR_12_INTERFACE + RRScreenSetSizeProcPtr rrScreenSetSize; + RRCrtcSetProcPtr rrCrtcSet; + RRCrtcSetGammaProcPtr rrCrtcSetGamma; + RROutputSetPropertyProcPtr rrOutputSetProperty; + RROutputValidateModeProcPtr rrOutputValidateMode; + RRModeDestroyProcPtr rrModeDestroy; +#endif + /* + * Private part of the structure; not considered part of the ABI + */ TimeStamp lastSetTime; /* last changed by client */ TimeStamp lastConfigTime; /* possible configs changed */ RRCloseScreenProcPtr CloseScreen; + Bool changed; /* some config changed */ + Bool configChanged; /* configuration changed */ + Bool layoutChanged; /* screen layout changed */ + + CARD16 minWidth, minHeight; + CARD16 maxWidth, maxHeight; + CARD16 width, height; /* last known screen size */ + CARD16 mmWidth, mmHeight; /* last known screen size */ + + int numOutputs; + RROutputPtr *outputs; + + int numCrtcs; + RRCrtcPtr *crtcs; + + /* Last known pointer position */ + RRCrtcPtr pointerCrtc; + +#ifdef RANDR_10_INTERFACE /* * Configuration information */ Rotation rotations; + CARD16 reqWidth, reqHeight; int nSizes; - int nSizesInUse; RRScreenSizePtr pSizes; - - /* - * Current state - */ + Rotation rotation; - int size; int rate; + int size; +#endif } rrScrPrivRec, *rrScrPrivPtr; +#ifndef NXAGENT_SERVER +extern DevPrivateKey rrPrivKey; +#else extern int rrPrivIndex; +#endif + +#ifndef NXAGENT_SERVER + +#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 #define rrGetScrPriv(pScr) ((rrScrPrivPtr) (pScr)->devPrivates[rrPrivIndex].ptr) #define rrScrPriv(pScr) rrScrPrivPtr pScrPriv = rrGetScrPriv(pScr) #define SetRRScreen(s,p) ((s)->devPrivates[rrPrivIndex].ptr = (pointer) (p)) +#endif + +/* + * each window has a list of clients requesting + * RRNotify events. Each client has a resource + * for each window it selects RRNotify input for, + * this resource is used to delete the RRNotifyRec + * entry from the per-window queue. + */ + +typedef struct _RREvent *RREventPtr; + +typedef struct _RREvent { + RREventPtr next; + ClientPtr client; + WindowPtr window; + XID clientResource; + int mask; +} RREventRec; + +typedef struct _RRTimes { + TimeStamp setTime; + TimeStamp configTime; +} RRTimesRec, *RRTimesPtr; + +typedef struct _RRClient { + int major_version; + int minor_version; +/* RRTimesRec times[0]; */ +} RRClientRec, *RRClientPtr; + +extern RESTYPE RRClientType, RREventType; /* resource types for event masks */ +#ifndef NXAGENT_SERVER +extern DevPrivateKey RRClientPrivateKey; +#else +extern int RRClientPrivateIndex; +#endif +extern RESTYPE RRCrtcType, RRModeType, RROutputType; + +#define LookupOutput(client,id,a) ((RROutputPtr) \ + (SecurityLookupIDByType (client, id, \ + RROutputType, a))) +#define LookupCrtc(client,id,a) ((RRCrtcPtr) \ + (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) + +#define DixUnknownAccess SecurityUnknownAccess +#define DixReadAccess SecurityReadAccess +#define DixWriteAccess SecurityWriteAccess +#define DixDestroyAccess SecurityDestroyAccess + +#endif + /* Initialize the extension */ void RRExtensionInit (void); +#ifdef RANDR_12_INTERFACE +/* + * Set the range of sizes for the screen + */ +void +RRScreenSetSizeRange (ScreenPtr pScreen, + CARD16 minWidth, + CARD16 minHeight, + CARD16 maxWidth, + CARD16 maxHeight); +#endif + +/* rrscreen.c */ +/* + * Notify the extension that the screen size has been changed. + * The driver is responsible for calling this whenever it has changed + * the size of the screen + */ +void +RRScreenSizeNotify (ScreenPtr pScreen); + +/* + * Request that the screen be resized + */ +Bool +RRScreenSizeSet (ScreenPtr pScreen, + CARD16 width, + CARD16 height, + CARD32 mmWidth, + CARD32 mmHeight); + +/* + * Send ConfigureNotify event to root window when 'something' happens + */ +void +RRSendConfigNotify (ScreenPtr pScreen); + +/* + * screen dispatch + */ +int +ProcRRGetScreenSizeRange (ClientPtr client); + +int +ProcRRSetScreenSize (ClientPtr client); + +int +ProcRRGetScreenResources (ClientPtr client); + +int +ProcRRSetScreenConfig (ClientPtr client); + +int +ProcRRGetScreenInfo (ClientPtr client); + +/* + * Deliver a ScreenNotify event + */ +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); + +/* randr.c */ +/* + * Send all pending events + */ +void +RRTellChanged (ScreenPtr pScreen); + +/* + * Poll the driver for changed information + */ +Bool +RRGetInfo (ScreenPtr pScreen); + +Bool RRInit (void); + +Bool RRScreenInit(ScreenPtr pScreen); + +RROutputPtr +RRFirstOutput (ScreenPtr pScreen); + +Rotation +RRGetRotation (ScreenPtr pScreen); + +CARD16 +RRVerticalRefresh (xRRModeInfo *mode); + +#ifdef RANDR_10_INTERFACE +/* + * This is the old interface, deprecated but left + * around for compatibility + */ + /* * Then, register the specific size with the screen */ @@ -116,7 +507,10 @@ RRSetCurrentConfig (ScreenPtr pScreen, int rate, RRScreenSizePtr pSize); -Bool RRScreenInit(ScreenPtr pScreen); +Bool RRScreenInit (ScreenPtr pScreen); + +Rotation +RRGetRotation (ScreenPtr pScreen); int RRSetScreenConfig (ScreenPtr pScreen, @@ -124,19 +518,371 @@ RRSetScreenConfig (ScreenPtr pScreen, int rate, RRScreenSizePtr pSize); +#endif + +/* rrcrtc.c */ + +/* + * Notify the CRTC of some change; layoutChanged indicates that + * some position or size element changed + */ +void +RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged); + +/* + * Create a CRTC + */ +RRCrtcPtr +RRCrtcCreate (ScreenPtr pScreen, void *devPrivate); + +/* + * Set the allowed rotations on a CRTC + */ +void +RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations); + +/* + * Notify the extension that the Crtc has been reconfigured, + * the driver calls this whenever it has updated the mode + */ Bool -miRandRInit (ScreenPtr pScreen); +RRCrtcNotify (RRCrtcPtr crtc, + RRModePtr mode, + int x, + int y, + Rotation rotation, + int numOutputs, + RROutputPtr *outputs); +void +RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc); + +/* + * Request that the Crtc be reconfigured + */ Bool -miRRGetInfo (ScreenPtr pScreen, Rotation *rotations); +RRCrtcSet (RRCrtcPtr crtc, + RRModePtr mode, + int x, + int y, + Rotation rotation, + int numOutput, + RROutputPtr *outputs); + +/* + * Request that the Crtc gamma be changed + */ Bool -miRRSetConfig (ScreenPtr pScreen, - Rotation rotation, - int rate, - RRScreenSizePtr size); +RRCrtcGammaSet (RRCrtcPtr crtc, + CARD16 *red, + CARD16 *green, + CARD16 *blue); + +/* + * 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 -miRRGetScreenInfo (ScreenPtr pScreen); +RRCrtcGammaNotify (RRCrtcPtr crtc); + +/* + * Set the size of the gamma table at server startup time + */ + +Bool +RRCrtcGammaSetSize (RRCrtcPtr crtc, + int size); + +/* + * Return the area of the frame buffer scanned out by the crtc, + * taking into account the current mode and rotation + */ + +void +RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height); + +/* + * Destroy a Crtc at shutdown + */ +void +RRCrtcDestroy (RRCrtcPtr crtc); + +/* + * Initialize crtc type + */ +Bool +RRCrtcInit (void); + +/* + * Crtc dispatch + */ + +int +ProcRRGetCrtcInfo (ClientPtr client); + +int +ProcRRSetCrtcConfig (ClientPtr client); + +int +ProcRRGetCrtcGammaSize (ClientPtr client); + +int +ProcRRGetCrtcGamma (ClientPtr client); + +int +ProcRRSetCrtcGamma (ClientPtr client); + +/* rrdispatch.c */ +Bool +RRClientKnowsRates (ClientPtr pClient); + +/* rrmode.c */ +/* + * Find, and if necessary, create a mode + */ + +RRModePtr +RRModeGet (xRRModeInfo *modeInfo, + const char *name); + +void +RRModePruneUnused (ScreenPtr pScreen); + +/* + * Destroy a mode. + */ + +void +RRModeDestroy (RRModePtr mode); + +/* + * Return a list of modes that are valid for some output in pScreen + */ +RRModePtr * +RRModesForScreen (ScreenPtr pScreen, int *num_ret); + +/* + * Initialize mode type + */ +Bool +RRModeInit (void); + +int +ProcRRCreateMode (ClientPtr client); + +int +ProcRRDestroyMode (ClientPtr client); + +int +ProcRRAddOutputMode (ClientPtr client); + +int +ProcRRDeleteOutputMode (ClientPtr client); + +/* rroutput.c */ + +/* + * Notify the output of some change. configChanged indicates whether + * any external configuration (mode list, clones, connected status) + * has changed, or whether the change was strictly internal + * (which crtc is in use) + */ +void +RROutputChanged (RROutputPtr output, Bool configChanged); + +/* + * Create an output + */ + +RROutputPtr +RROutputCreate (ScreenPtr pScreen, + const char *name, + int nameLength, + void *devPrivate); + +/* + * Notify extension that output parameters have been changed + */ +Bool +RROutputSetClones (RROutputPtr output, + RROutputPtr *clones, + int numClones); + +Bool +RROutputSetModes (RROutputPtr output, + RRModePtr *modes, + int numModes, + int numPreferred); + +int +RROutputAddUserMode (RROutputPtr output, + RRModePtr mode); + +int +RROutputDeleteUserMode (RROutputPtr output, + RRModePtr mode); + +Bool +RROutputSetCrtcs (RROutputPtr output, + RRCrtcPtr *crtcs, + int numCrtcs); + +Bool +RROutputSetConnection (RROutputPtr output, + CARD8 connection); + +Bool +RROutputSetSubpixelOrder (RROutputPtr output, + int subpixelOrder); + +Bool +RROutputSetPhysicalSize (RROutputPtr output, + int mmWidth, + int mmHeight); + +void +RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output); + +void +RROutputDestroy (RROutputPtr output); + +int +ProcRRGetOutputInfo (ClientPtr client); + +/* + * Initialize output type + */ +Bool +RROutputInit (void); + +/* rrpointer.c */ +void +RRPointerMoved (ScreenPtr pScreen, int x, int y); + +void +RRPointerScreenConfigured (ScreenPtr pScreen); + +/* rrproperty.c */ + +void +RRDeleteAllOutputProperties (RROutputPtr output); + +RRPropertyValuePtr +RRGetOutputProperty (RROutputPtr output, Atom property, Bool pending); + +RRPropertyPtr +RRQueryOutputProperty (RROutputPtr output, Atom property); + +void +RRDeleteOutputProperty (RROutputPtr output, Atom property); + +Bool +RRPostPendingProperties (RROutputPtr output); + +int +RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type, + int format, int mode, unsigned long len, + pointer value, Bool sendevent, Bool pending); + +int +RRConfigureOutputProperty (RROutputPtr output, Atom property, + Bool pending, Bool range, Bool immutable, + int num_values, INT32 *values); +int +ProcRRChangeOutputProperty (ClientPtr client); + +int +ProcRRGetOutputProperty (ClientPtr client); + +int +ProcRRListOutputProperties (ClientPtr client); + +int +ProcRRQueryOutputProperty (ClientPtr client); + +int +ProcRRConfigureOutputProperty (ClientPtr client); + +int +ProcRRDeleteOutputProperty (ClientPtr client); + +/* rrxinerama.c */ +void +RRXineramaExtensionInit(void); #endif /* _RANDRSTR_H_ */ + +/* + +randr extension implementation structure + +Query state: + ProcRRGetScreenInfo/ProcRRGetScreenResources + RRGetInfo + + • Request configuration from driver, either 1.0 or 1.2 style + • These functions only record state changes, all + other actions are pended until RRTellChanged is called + + ->rrGetInfo + 1.0: + RRRegisterSize + RRRegisterRate + RRSetCurrentConfig + 1.2: + RRScreenSetSizeRange + RROutputSetCrtcs + RRModeGet + RROutputSetModes + RROutputSetConnection + RROutputSetSubpixelOrder + RROutputSetClones + RRCrtcNotify + + • Must delay scanning configuration until after ->rrGetInfo returns + because some drivers will call SetCurrentConfig in the middle + of the ->rrGetInfo operation. + + 1.0: + + • Scan old configuration, mirror to new structures + + RRScanOldConfig + RRCrtcCreate + RROutputCreate + RROutputSetCrtcs + RROutputSetConnection + RROutputSetSubpixelOrder + RROldModeAdd • This adds modes one-at-a-time + RRModeGet + RRCrtcNotify + + • send events, reset pointer if necessary + + RRTellChanged + WalkTree (sending events) + + • when layout has changed: + RRPointerScreenConfigured + RRSendConfigNotify + +Asynchronous state setting (1.2 only) + When setting state asynchronously, the driver invokes the + ->rrGetInfo function and then calls RRTellChanged to flush + the changes to the clients and reset pointer if necessary + +Set state + + ProcRRSetScreenConfig + RRCrtcSet + 1.2: + ->rrCrtcSet + RRCrtcNotify + 1.0: + ->rrSetConfig + RRCrtcNotify + RRTellChanged + */ diff --git a/programs/Xserver/randr/registry.h b/programs/Xserver/randr/registry.h new file mode 100644 index 0000000..29e5fdf --- /dev/null +++ b/programs/Xserver/randr/registry.h @@ -0,0 +1,64 @@ +/*********************************************************** + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +******************************************************************/ + +#ifndef DIX_REGISTRY_H +#define DIX_REGISTRY_H + +/* + * Result returned from any unsuccessful lookup + */ +#define XREGISTRY_UNKNOWN "<unknown>" + +#ifdef XREGISTRY + +#include "resource.h" +#include "extnsionst.h" + +/* Internal string registry - for auditing, debugging, security, etc. */ + +/* + * Registration functions. The name string is not copied, so it must + * not be a stack variable. + */ +void RegisterResourceName(RESTYPE type, char *name); +void RegisterExtensionNames(ExtensionEntry *ext); + +/* + * Lookup functions. The returned string must not be modified or freed. + */ +const char *LookupMajorName(int major); +const char *LookupRequestName(int major, int minor); +const char *LookupEventName(int event); +const char *LookupErrorName(int error); +const char *LookupResourceName(RESTYPE rtype); + +/* + * Setup and teardown + */ +void dixResetRegistry(void); + +#else /* XREGISTRY */ + +/* Define calls away when the registry is not being built. */ + +#define RegisterResourceName(a, b) { ; } +#define RegisterExtensionNames(a) { ; } + +#define LookupMajorName(a) XREGISTRY_UNKNOWN +#define LookupRequestName(a, b) XREGISTRY_UNKNOWN +#define LookupEventName(a) XREGISTRY_UNKNOWN +#define LookupErrorName(a) XREGISTRY_UNKNOWN +#define LookupResourceName(a) XREGISTRY_UNKNOWN + +#define dixResetRegistry() { ; } + +#endif /* XREGISTRY */ +#endif /* DIX_REGISTRY_H */ diff --git a/programs/Xserver/randr/registry.h.NX.original b/programs/Xserver/randr/registry.h.NX.original new file mode 100644 index 0000000..29e5fdf --- /dev/null +++ b/programs/Xserver/randr/registry.h.NX.original @@ -0,0 +1,64 @@ +/*********************************************************** + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +******************************************************************/ + +#ifndef DIX_REGISTRY_H +#define DIX_REGISTRY_H + +/* + * Result returned from any unsuccessful lookup + */ +#define XREGISTRY_UNKNOWN "<unknown>" + +#ifdef XREGISTRY + +#include "resource.h" +#include "extnsionst.h" + +/* Internal string registry - for auditing, debugging, security, etc. */ + +/* + * Registration functions. The name string is not copied, so it must + * not be a stack variable. + */ +void RegisterResourceName(RESTYPE type, char *name); +void RegisterExtensionNames(ExtensionEntry *ext); + +/* + * Lookup functions. The returned string must not be modified or freed. + */ +const char *LookupMajorName(int major); +const char *LookupRequestName(int major, int minor); +const char *LookupEventName(int event); +const char *LookupErrorName(int error); +const char *LookupResourceName(RESTYPE rtype); + +/* + * Setup and teardown + */ +void dixResetRegistry(void); + +#else /* XREGISTRY */ + +/* Define calls away when the registry is not being built. */ + +#define RegisterResourceName(a, b) { ; } +#define RegisterExtensionNames(a) { ; } + +#define LookupMajorName(a) XREGISTRY_UNKNOWN +#define LookupRequestName(a, b) XREGISTRY_UNKNOWN +#define LookupEventName(a) XREGISTRY_UNKNOWN +#define LookupErrorName(a) XREGISTRY_UNKNOWN +#define LookupResourceName(a) XREGISTRY_UNKNOWN + +#define dixResetRegistry() { ; } + +#endif /* XREGISTRY */ +#endif /* DIX_REGISTRY_H */ diff --git a/CHANGELOG.X.original b/programs/Xserver/randr/registry.h.X.original similarity index 100% copy from CHANGELOG.X.original copy to programs/Xserver/randr/registry.h.X.original diff --git a/programs/Xserver/randr/rrcrtc.c b/programs/Xserver/randr/rrcrtc.c new file mode 100644 index 0000000..fb82a80 --- /dev/null +++ b/programs/Xserver/randr/rrcrtc.c @@ -0,0 +1,984 @@ +/* + * 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. + */ + +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */ +/* */ +/* NX-X11, NX protocol compression and NX extensions to this software */ +/* are copyright of NoMachine. Redistribution and use of the present */ +/* software is allowed according to terms specified in the file LICENSE */ +/* which comes in the source distribution. */ +/* */ +/* Check http://www.nomachine.com/licensing.html for applicability. */ +/* */ +/* NX and NoMachine are trademarks of Medialogic S.p.A. */ +/* */ +/* All rights reserved. */ +/* */ +/**************************************************************************/ + +#include "randrstr.h" +#include "swaprep.h" +#include "registry.h" + +RESTYPE RRCrtcType; + +/* + * Notify the CRTC of some change + */ +void +RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged) +{ + ScreenPtr pScreen = crtc->pScreen; + + crtc->changed = TRUE; + if (pScreen) + { + rrScrPriv(pScreen); + + pScrPriv->changed = TRUE; + /* + * Send ConfigureNotify on any layout change + */ + if (layoutChanged) + pScrPriv->layoutChanged = TRUE; + } +} + +/* + * Create a CRTC + */ +RRCrtcPtr +RRCrtcCreate (ScreenPtr pScreen, void *devPrivate) +{ + RRCrtcPtr crtc; + RRCrtcPtr *crtcs; + rrScrPrivPtr pScrPriv; + + if (!RRInit()) + return NULL; + + pScrPriv = rrGetScrPriv(pScreen); + + /* make space for the crtc pointer */ + if (pScrPriv->numCrtcs) + crtcs = xrealloc (pScrPriv->crtcs, + (pScrPriv->numCrtcs + 1) * sizeof (RRCrtcPtr)); + else + crtcs = xalloc (sizeof (RRCrtcPtr)); + if (!crtcs) + return FALSE; + pScrPriv->crtcs = crtcs; + + crtc = xcalloc (1, sizeof (RRCrtcRec)); + if (!crtc) + return NULL; + crtc->id = FakeClientID (0); + crtc->pScreen = pScreen; + crtc->mode = NULL; + crtc->x = 0; + crtc->y = 0; + crtc->rotation = RR_Rotate_0; + crtc->rotations = RR_Rotate_0; + crtc->outputs = NULL; + crtc->numOutputs = 0; + crtc->gammaSize = 0; + crtc->gammaRed = crtc->gammaBlue = crtc->gammaGreen = NULL; + crtc->changed = FALSE; + crtc->devPrivate = devPrivate; + + if (!AddResource (crtc->id, RRCrtcType, (pointer) crtc)) + return NULL; + + /* attach the screen and crtc together */ + crtc->pScreen = pScreen; + pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc; + + return crtc; +} + +/* + * Set the allowed rotations on a CRTC + */ +void +RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations) +{ + crtc->rotations = rotations; +} + +/* + * Notify the extension that the Crtc has been reconfigured, + * the driver calls this whenever it has updated the mode + */ +Bool +RRCrtcNotify (RRCrtcPtr crtc, + RRModePtr mode, + int x, + int y, + Rotation rotation, + int numOutputs, + RROutputPtr *outputs) +{ + int i, j; + + /* + * Check to see if any of the new outputs were + * not in the old list and mark them as changed + */ + for (i = 0; i < numOutputs; i++) + { + for (j = 0; j < crtc->numOutputs; j++) + if (outputs[i] == crtc->outputs[j]) + break; + if (j == crtc->numOutputs) + { + outputs[i]->crtc = crtc; + RROutputChanged (outputs[i], FALSE); + RRCrtcChanged (crtc, FALSE); + } + } + /* + * Check to see if any of the old outputs are + * not in the new list and mark them as changed + */ + for (j = 0; j < crtc->numOutputs; j++) + { + for (i = 0; i < numOutputs; i++) + if (outputs[i] == crtc->outputs[j]) + break; + if (i == numOutputs) + { + if (crtc->outputs[j]->crtc == crtc) + crtc->outputs[j]->crtc = NULL; + RROutputChanged (crtc->outputs[j], FALSE); + RRCrtcChanged (crtc, FALSE); + } + } + /* + * Reallocate the crtc output array if necessary + */ + if (numOutputs != crtc->numOutputs) + { + RROutputPtr *newoutputs; + + if (numOutputs) + { + if (crtc->numOutputs) + newoutputs = xrealloc (crtc->outputs, + numOutputs * sizeof (RROutputPtr)); + else + newoutputs = xalloc (numOutputs * sizeof (RROutputPtr)); + if (!newoutputs) + return FALSE; + } + else + { + if (crtc->outputs) + xfree (crtc->outputs); + newoutputs = NULL; + } + crtc->outputs = newoutputs; + crtc->numOutputs = numOutputs; + } + /* + * Copy the new list of outputs into the crtc + */ + memcpy (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)); + /* + * Update remaining crtc fields + */ + if (mode != crtc->mode) + { + if (crtc->mode) + RRModeDestroy (crtc->mode); + crtc->mode = mode; + if (mode != NULL) + mode->refcnt++; + RRCrtcChanged (crtc, TRUE); + } + if (x != crtc->x) + { + crtc->x = x; + RRCrtcChanged (crtc, TRUE); + } + if (y != crtc->y) + { + crtc->y = y; + RRCrtcChanged (crtc, TRUE); + } + if (rotation != crtc->rotation) + { + crtc->rotation = rotation; + RRCrtcChanged (crtc, TRUE); + } + return TRUE; +} + +void +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; + } + WriteEventsToClient (client, 1, (xEvent *) &ce); +} + +static Bool +RRCrtcPendingProperties (RRCrtcPtr crtc) +{ + ScreenPtr pScreen = crtc->pScreen; + rrScrPriv(pScreen); + int o; + + for (o = 0; o < pScrPriv->numOutputs; o++) + { + RROutputPtr output = pScrPriv->outputs[o]; + if (output->crtc == crtc && output->pendingProperties) + return TRUE; + } + return FALSE; +} + +/* + * Request that the Crtc be reconfigured + */ +Bool +RRCrtcSet (RRCrtcPtr crtc, + RRModePtr mode, + int x, + int y, + Rotation rotation, + int numOutputs, + RROutputPtr *outputs) +{ + ScreenPtr pScreen = crtc->pScreen; + Bool ret = FALSE; + rrScrPriv(pScreen); + + /* See if nothing changed */ + if (crtc->mode == mode && + crtc->x == x && + crtc->y == y && + crtc->rotation == rotation && + crtc->numOutputs == numOutputs && + !memcmp (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)) && + !RRCrtcPendingProperties (crtc)) + { + ret = TRUE; + } + else + { +#if RANDR_12_INTERFACE + if (pScrPriv->rrCrtcSet) + { + ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y, + rotation, numOutputs, outputs); + } + else +#endif + { +#if RANDR_10_INTERFACE + if (pScrPriv->rrSetConfig) + { + RRScreenSize size; + RRScreenRate rate; + + if (!mode) + { + RRCrtcNotify (crtc, NULL, x, y, rotation, 0, NULL); + ret = TRUE; + } + else + { + size.width = mode->mode.width; + size.height = mode->mode.height; + if (outputs[0]->mmWidth && outputs[0]->mmHeight) + { + size.mmWidth = outputs[0]->mmWidth; + size.mmHeight = outputs[0]->mmHeight; + } + else + { + size.mmWidth = pScreen->mmWidth; + size.mmHeight = pScreen->mmHeight; + } + size.nRates = 1; + rate.rate = RRVerticalRefresh (&mode->mode); + size.pRates = &rate; + ret = (*pScrPriv->rrSetConfig) (pScreen, rotation, rate.rate, &size); + /* + * Old 1.0 interface tied screen size to mode size + */ + if (ret) + { + RRCrtcNotify (crtc, mode, x, y, rotation, 1, outputs); + RRScreenSizeNotify (pScreen); + } + } + } +#endif + } + if (ret) + { + int o; + RRTellChanged (pScreen); + + for (o = 0; o < numOutputs; o++) + RRPostPendingProperties (outputs[o]); + } + } + return ret; +} + +/* + * Destroy a Crtc at shutdown + */ +void +RRCrtcDestroy (RRCrtcPtr crtc) +{ + FreeResource (crtc->id, 0); +} + +static int +RRCrtcDestroyResource (pointer value, XID pid) +{ + RRCrtcPtr crtc = (RRCrtcPtr) value; + ScreenPtr pScreen = crtc->pScreen; + + if (pScreen) + { + rrScrPriv(pScreen); + int i; + + for (i = 0; i < pScrPriv->numCrtcs; i++) + { + if (pScrPriv->crtcs[i] == crtc) + { + memmove (pScrPriv->crtcs + i, pScrPriv->crtcs + i + 1, + (pScrPriv->numCrtcs - (i + 1)) * sizeof (RRCrtcPtr)); + --pScrPriv->numCrtcs; + break; + } + } + } + if (crtc->gammaRed) + xfree (crtc->gammaRed); + if (crtc->mode) + RRModeDestroy (crtc->mode); + xfree (crtc); + return 1; +} + +/* + * Request that the Crtc gamma be changed + */ + +Bool +RRCrtcGammaSet (RRCrtcPtr crtc, + CARD16 *red, + CARD16 *green, + CARD16 *blue) +{ + Bool ret = TRUE; +#if RANDR_12_INTERFACE + ScreenPtr pScreen = crtc->pScreen; +#endif + + memcpy (crtc->gammaRed, red, crtc->gammaSize * sizeof (CARD16)); + memcpy (crtc->gammaGreen, green, crtc->gammaSize * sizeof (CARD16)); + memcpy (crtc->gammaBlue, blue, crtc->gammaSize * sizeof (CARD16)); +#if RANDR_12_INTERFACE + if (pScreen) + { + rrScrPriv(pScreen); + if (pScrPriv->rrCrtcSetGamma) + ret = (*pScrPriv->rrCrtcSetGamma) (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 + * in the RRCrtcRec + */ + +Bool +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) +{ + if (crtc->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; + } +} + +/* + * Set the size of the gamma table at server startup time + */ + +Bool +RRCrtcGammaSetSize (RRCrtcPtr crtc, + int size) +{ + CARD16 *gamma; + + if (size == crtc->gammaSize) + return TRUE; + if (size) + { + gamma = xalloc (size * 3 * sizeof (CARD16)); + if (!gamma) + return FALSE; + } + else + gamma = NULL; + if (crtc->gammaRed) + xfree (crtc->gammaRed); + crtc->gammaRed = gamma; + crtc->gammaGreen = gamma + size; + crtc->gammaBlue = gamma + size*2; + crtc->gammaSize = size; + return TRUE; +} + +/* + * Initialize crtc type + */ +Bool +RRCrtcInit (void) +{ + RRCrtcType = CreateNewResourceType (RRCrtcDestroyResource); + if (!RRCrtcType) + return FALSE; + RegisterResourceName (RRCrtcType, "CRTC"); + return TRUE; +} + +int +ProcRRGetCrtcInfo (ClientPtr client) +{ + REQUEST(xRRGetCrtcInfoReq); + xRRGetCrtcInfoReply rep; + RRCrtcPtr crtc; + CARD8 *extra; + unsigned long extraLen; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + RRModePtr mode; + RROutput *outputs; + RROutput *possible; + int i, j, k, n; + int width, height; + + REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq); + crtc = LookupCrtc(client, stuff->crtc, DixReadAccess); + + if (!crtc) + return RRErrorBase + BadRRCrtc; + + /* All crtcs must be associated with screens before client + * requests are processed + */ + pScreen = crtc->pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + 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.mode = mode ? mode->mode.id : 0; + rep.rotation = crtc->rotation; + rep.rotations = crtc->rotations; + rep.nOutput = crtc->numOutputs; + k = 0; + for (i = 0; i < pScrPriv->numOutputs; i++) + for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++) + if (pScrPriv->outputs[i]->crtcs[j] == crtc) + k++; + rep.nPossibleOutput = k; + + rep.length = rep.nOutput + rep.nPossibleOutput; + + extraLen = rep.length << 2; + if (extraLen) + { + extra = xalloc (extraLen); + if (!extra) + return BadAlloc; + } + else + extra = NULL; + + outputs = (RROutput *) extra; + possible = (RROutput *) (outputs + rep.nOutput); + + for (i = 0; i < crtc->numOutputs; i++) + { + outputs[i] = crtc->outputs[i]->id; + if (client->swapped) + swapl (&outputs[i], n); + } + k = 0; + for (i = 0; i < pScrPriv->numOutputs; i++) + for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++) + if (pScrPriv->outputs[i]->crtcs[j] == crtc) + { + possible[k] = pScrPriv->outputs[i]->id; + if (client->swapped) + swapl (&possible[k], n); + k++; + } + + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.timestamp, n); + swaps(&rep.x, n); + swaps(&rep.y, n); + swaps(&rep.width, n); + swaps(&rep.height, n); + swapl(&rep.mode, n); + swaps(&rep.rotation, n); + swaps(&rep.rotations, n); + swaps(&rep.nOutput, n); + swaps(&rep.nPossibleOutput, n); + } + WriteToClient(client, sizeof(xRRGetCrtcInfoReply), (char *)&rep); + if (extraLen) + { + WriteToClient (client, extraLen, (char *) extra); + xfree (extra); + } + + return client->noClientException; +} + +int +ProcRRSetCrtcConfig (ClientPtr client) +{ + REQUEST(xRRSetCrtcConfigReq); + xRRSetCrtcConfigReply rep; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + RRCrtcPtr crtc; + RRModePtr mode; + int numOutputs; + RROutputPtr *outputs = NULL; + RROutput *outputIds; + TimeStamp configTime; + TimeStamp time; + Rotation rotation; + int i, j; + + REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq); + numOutputs = (stuff->length - (SIZEOF (xRRSetCrtcConfigReq) >> 2)); + + 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; + } + if (numOutputs == 0) + return BadMatch; + } + if (numOutputs) + { + outputs = xalloc (numOutputs * sizeof (RROutputPtr)); + if (!outputs) + return BadAlloc; + } + else + outputs = NULL; + + outputIds = (RROutput *) (stuff + 1); + for (i = 0; i < numOutputs; i++) + { + outputs[i] = (RROutputPtr) LookupIDByType (outputIds[i], RROutputType); + if (!outputs[i]) + { + client->errorValue = outputIds[i]; + if (outputs) + xfree (outputs); + return RRErrorBase + BadRROutput; + } + /* 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); + return BadMatch; + } + /* validate mode for this output */ + for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++) + { + RRModePtr m = (j < outputs[i]->numModes ? + outputs[i]->modes[j] : + outputs[i]->userModes[j - outputs[i]->numModes]); + if (m == mode) + break; + } + if (j == outputs[i]->numModes + outputs[i]->numUserModes) + { + if (outputs) + xfree (outputs); + return BadMatch; + } + } + /* validate clones */ + for (i = 0; i < numOutputs; i++) + { + for (j = 0; j < numOutputs; j++) + { + int k; + if (i == j) + continue; + for (k = 0; k < outputs[i]->numClones; k++) + { + if (outputs[i]->clones[k] == outputs[j]) + break; + } + if (k == outputs[i]->numClones) + { + if (outputs) + xfree (outputs); + return BadMatch; + } + } + } + + pScreen = crtc->pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + time = ClientTimeToServerTime(stuff->timestamp); + configTime = ClientTimeToServerTime(stuff->configTimestamp); + + if (!pScrPriv) + { + time = currentTime; + rep.status = RRSetConfigFailed; + goto sendReply; + } + +#if 0 + /* + * if the client's config timestamp is not the same as the last config + * timestamp, then the config information isn't up-to-date and + * can't even be validated + */ + if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0) + { + rep.status = RRSetConfigInvalidConfigTime; + goto sendReply; + } +#endif + + /* + * Validate requested rotation + */ + rotation = (Rotation) stuff->rotation; + + /* test the rotation bits only! */ + switch (rotation & 0xf) { + case RR_Rotate_0: + case RR_Rotate_90: + case RR_Rotate_180: + case RR_Rotate_270: + break; + default: + /* + * Invalid rotation + */ + client->errorValue = stuff->rotation; + if (outputs) + xfree (outputs); + return BadValue; + } + + if (mode) + { + if ((~crtc->rotations) & rotation) + { + /* + * requested rotation or reflection not supported by screen + */ + client->errorValue = stuff->rotation; + if (outputs) + xfree (outputs); + return BadMatch; + } + +#ifdef RANDR_12_INTERFACE + /* + * 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 + */ + 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 (stuff->x + source_width > pScreen->width) + { + client->errorValue = stuff->x; + if (outputs) + xfree (outputs); + return BadValue; + } + + if (stuff->y + source_height > pScreen->height) + { + client->errorValue = stuff->y; + if (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; + goto sendReply; + } + #ifdef NXAGENT_SERVER /* Bug 21987 */ + pScrPriv->lastSetTime = time; + #endif + rep.status = RRSetConfigSuccess; + +sendReply: + if (outputs) + xfree (outputs); + + rep.type = X_Reply; + /* rep.status has already been filled in */ + rep.length = 0; + rep.sequenceNumber = client->sequence; + #ifndef NXAGENT_SERVER /* Bug 21987 */ + rep.newTimestamp = pScrPriv->lastConfigTime.milliseconds; + #else + rep.newTimestamp = pScrPriv->lastSetTime.milliseconds; + #endif + + if (client->swapped) + { + int n; + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.newTimestamp, n); + } + WriteToClient(client, sizeof(xRRSetCrtcConfigReply), (char *)&rep); + + return client->noClientException; +} + +int +ProcRRGetCrtcGammaSize (ClientPtr client) +{ + REQUEST(xRRGetCrtcGammaSizeReq); + xRRGetCrtcGammaSizeReply reply; + RRCrtcPtr crtc; + int n; + + REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq); + crtc = LookupCrtc (client, stuff->crtc, DixReadAccess); + if (!crtc) + return RRErrorBase + BadRRCrtc; + + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.length = 0; + reply.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; +} + +int +ProcRRGetCrtcGamma (ClientPtr client) +{ + REQUEST(xRRGetCrtcGammaReq); + xRRGetCrtcGammaReply reply; + RRCrtcPtr crtc; + int n; + unsigned long len; + char *extra; + + REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq); + crtc = LookupCrtc (client, stuff->crtc, DixReadAccess); + if (!crtc) + return RRErrorBase + BadRRCrtc; + + len = crtc->gammaSize * 3 * 2; + + if (crtc->gammaSize) { + extra = xalloc(len); + if (!extra) + return BadAlloc; + } + + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.length = (len + 3) >> 2; + reply.size = crtc->gammaSize; + if (client->swapped) { + swaps (&reply.sequenceNumber, n); + swapl (&reply.length, n); + swaps (&reply.size, n); + } + WriteToClient (client, sizeof (xRRGetCrtcGammaReply), (char *) &reply); + if (crtc->gammaSize) + { + memcpy(extra, crtc->gammaRed, len); + client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; + WriteSwappedDataToClient (client, len, extra); + xfree(extra); + } + return client->noClientException; +} + +int +ProcRRSetCrtcGamma (ClientPtr client) +{ + REQUEST(xRRSetCrtcGammaReq); + RRCrtcPtr crtc; + unsigned long len; + CARD16 *red, *green, *blue; + + REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq); + crtc = LookupCrtc (client, stuff->crtc, DixWriteAccess); + if (!crtc) + return RRErrorBase + BadRRCrtc; + + len = client->req_len - (sizeof (xRRSetCrtcGammaReq) >> 2); + if (len < (stuff->size * 3 + 1) >> 1) + return BadLength; + + if (stuff->size != crtc->gammaSize) + return BadMatch; + + red = (CARD16 *) (stuff + 1); + green = red + crtc->gammaSize; + blue = green + crtc->gammaSize; + + RRCrtcGammaSet (crtc, red, green, blue); + + return Success; +} + diff --git a/programs/Xserver/randr/rrcrtc.c.NX.original b/programs/Xserver/randr/rrcrtc.c.NX.original new file mode 100644 index 0000000..fb82a80 --- /dev/null +++ b/programs/Xserver/randr/rrcrtc.c.NX.original @@ -0,0 +1,984 @@ +/* + * 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. + */ + +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */ +/* */ +/* NX-X11, NX protocol compression and NX extensions to this software */ +/* are copyright of NoMachine. Redistribution and use of the present */ +/* software is allowed according to terms specified in the file LICENSE */ +/* which comes in the source distribution. */ +/* */ +/* Check http://www.nomachine.com/licensing.html for applicability. */ +/* */ +/* NX and NoMachine are trademarks of Medialogic S.p.A. */ +/* */ +/* All rights reserved. */ +/* */ +/**************************************************************************/ + +#include "randrstr.h" +#include "swaprep.h" +#include "registry.h" + +RESTYPE RRCrtcType; + +/* + * Notify the CRTC of some change + */ +void +RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged) +{ + ScreenPtr pScreen = crtc->pScreen; + + crtc->changed = TRUE; + if (pScreen) + { + rrScrPriv(pScreen); + + pScrPriv->changed = TRUE; + /* + * Send ConfigureNotify on any layout change + */ + if (layoutChanged) + pScrPriv->layoutChanged = TRUE; + } +} + +/* + * Create a CRTC + */ +RRCrtcPtr +RRCrtcCreate (ScreenPtr pScreen, void *devPrivate) +{ + RRCrtcPtr crtc; + RRCrtcPtr *crtcs; + rrScrPrivPtr pScrPriv; + + if (!RRInit()) + return NULL; + + pScrPriv = rrGetScrPriv(pScreen); + + /* make space for the crtc pointer */ + if (pScrPriv->numCrtcs) + crtcs = xrealloc (pScrPriv->crtcs, + (pScrPriv->numCrtcs + 1) * sizeof (RRCrtcPtr)); + else + crtcs = xalloc (sizeof (RRCrtcPtr)); + if (!crtcs) + return FALSE; + pScrPriv->crtcs = crtcs; + + crtc = xcalloc (1, sizeof (RRCrtcRec)); + if (!crtc) + return NULL; + crtc->id = FakeClientID (0); + crtc->pScreen = pScreen; + crtc->mode = NULL; + crtc->x = 0; + crtc->y = 0; + crtc->rotation = RR_Rotate_0; + crtc->rotations = RR_Rotate_0; + crtc->outputs = NULL; + crtc->numOutputs = 0; + crtc->gammaSize = 0; + crtc->gammaRed = crtc->gammaBlue = crtc->gammaGreen = NULL; + crtc->changed = FALSE; + crtc->devPrivate = devPrivate; + + if (!AddResource (crtc->id, RRCrtcType, (pointer) crtc)) + return NULL; + + /* attach the screen and crtc together */ + crtc->pScreen = pScreen; + pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc; + + return crtc; +} + +/* + * Set the allowed rotations on a CRTC + */ +void +RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations) +{ + crtc->rotations = rotations; +} + +/* + * Notify the extension that the Crtc has been reconfigured, + * the driver calls this whenever it has updated the mode + */ +Bool +RRCrtcNotify (RRCrtcPtr crtc, + RRModePtr mode, + int x, + int y, + Rotation rotation, + int numOutputs, + RROutputPtr *outputs) +{ + int i, j; + + /* + * Check to see if any of the new outputs were + * not in the old list and mark them as changed + */ + for (i = 0; i < numOutputs; i++) + { + for (j = 0; j < crtc->numOutputs; j++) + if (outputs[i] == crtc->outputs[j]) + break; + if (j == crtc->numOutputs) + { + outputs[i]->crtc = crtc; + RROutputChanged (outputs[i], FALSE); + RRCrtcChanged (crtc, FALSE); + } + } + /* + * Check to see if any of the old outputs are + * not in the new list and mark them as changed + */ + for (j = 0; j < crtc->numOutputs; j++) + { + for (i = 0; i < numOutputs; i++) + if (outputs[i] == crtc->outputs[j]) + break; + if (i == numOutputs) + { + if (crtc->outputs[j]->crtc == crtc) + crtc->outputs[j]->crtc = NULL; + RROutputChanged (crtc->outputs[j], FALSE); + RRCrtcChanged (crtc, FALSE); + } + } + /* + * Reallocate the crtc output array if necessary + */ + if (numOutputs != crtc->numOutputs) + { + RROutputPtr *newoutputs; + + if (numOutputs) + { + if (crtc->numOutputs) + newoutputs = xrealloc (crtc->outputs, + numOutputs * sizeof (RROutputPtr)); + else + newoutputs = xalloc (numOutputs * sizeof (RROutputPtr)); + if (!newoutputs) + return FALSE; + } + else + { + if (crtc->outputs) + xfree (crtc->outputs); + newoutputs = NULL; + } + crtc->outputs = newoutputs; + crtc->numOutputs = numOutputs; + } + /* + * Copy the new list of outputs into the crtc + */ + memcpy (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)); + /* + * Update remaining crtc fields + */ + if (mode != crtc->mode) + { + if (crtc->mode) + RRModeDestroy (crtc->mode); + crtc->mode = mode; + if (mode != NULL) + mode->refcnt++; + RRCrtcChanged (crtc, TRUE); + } + if (x != crtc->x) + { + crtc->x = x; + RRCrtcChanged (crtc, TRUE); + } + if (y != crtc->y) + { + crtc->y = y; + RRCrtcChanged (crtc, TRUE); + } + if (rotation != crtc->rotation) + { + crtc->rotation = rotation; + RRCrtcChanged (crtc, TRUE); + } + return TRUE; +} + +void +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; + } + WriteEventsToClient (client, 1, (xEvent *) &ce); +} + +static Bool +RRCrtcPendingProperties (RRCrtcPtr crtc) +{ + ScreenPtr pScreen = crtc->pScreen; + rrScrPriv(pScreen); + int o; + + for (o = 0; o < pScrPriv->numOutputs; o++) + { + RROutputPtr output = pScrPriv->outputs[o]; + if (output->crtc == crtc && output->pendingProperties) + return TRUE; + } + return FALSE; +} + +/* + * Request that the Crtc be reconfigured + */ +Bool +RRCrtcSet (RRCrtcPtr crtc, + RRModePtr mode, + int x, + int y, + Rotation rotation, + int numOutputs, + RROutputPtr *outputs) +{ + ScreenPtr pScreen = crtc->pScreen; + Bool ret = FALSE; + rrScrPriv(pScreen); + + /* See if nothing changed */ + if (crtc->mode == mode && + crtc->x == x && + crtc->y == y && + crtc->rotation == rotation && + crtc->numOutputs == numOutputs && + !memcmp (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)) && + !RRCrtcPendingProperties (crtc)) + { + ret = TRUE; + } + else + { +#if RANDR_12_INTERFACE + if (pScrPriv->rrCrtcSet) + { + ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y, + rotation, numOutputs, outputs); + } + else +#endif + { +#if RANDR_10_INTERFACE + if (pScrPriv->rrSetConfig) + { + RRScreenSize size; + RRScreenRate rate; + + if (!mode) + { + RRCrtcNotify (crtc, NULL, x, y, rotation, 0, NULL); + ret = TRUE; + } + else + { + size.width = mode->mode.width; + size.height = mode->mode.height; + if (outputs[0]->mmWidth && outputs[0]->mmHeight) + { + size.mmWidth = outputs[0]->mmWidth; + size.mmHeight = outputs[0]->mmHeight; + } + else + { + size.mmWidth = pScreen->mmWidth; + size.mmHeight = pScreen->mmHeight; + } + size.nRates = 1; + rate.rate = RRVerticalRefresh (&mode->mode); + size.pRates = &rate; + ret = (*pScrPriv->rrSetConfig) (pScreen, rotation, rate.rate, &size); + /* + * Old 1.0 interface tied screen size to mode size + */ + if (ret) + { + RRCrtcNotify (crtc, mode, x, y, rotation, 1, outputs); + RRScreenSizeNotify (pScreen); + } + } + } +#endif + } + if (ret) + { + int o; + RRTellChanged (pScreen); + + for (o = 0; o < numOutputs; o++) + RRPostPendingProperties (outputs[o]); + } + } + return ret; +} + +/* + * Destroy a Crtc at shutdown + */ +void +RRCrtcDestroy (RRCrtcPtr crtc) +{ + FreeResource (crtc->id, 0); +} + +static int +RRCrtcDestroyResource (pointer value, XID pid) +{ + RRCrtcPtr crtc = (RRCrtcPtr) value; + ScreenPtr pScreen = crtc->pScreen; + + if (pScreen) + { + rrScrPriv(pScreen); + int i; + + for (i = 0; i < pScrPriv->numCrtcs; i++) + { + if (pScrPriv->crtcs[i] == crtc) + { + memmove (pScrPriv->crtcs + i, pScrPriv->crtcs + i + 1, + (pScrPriv->numCrtcs - (i + 1)) * sizeof (RRCrtcPtr)); + --pScrPriv->numCrtcs; + break; + } + } + } + if (crtc->gammaRed) + xfree (crtc->gammaRed); + if (crtc->mode) + RRModeDestroy (crtc->mode); + xfree (crtc); + return 1; +} + +/* + * Request that the Crtc gamma be changed + */ + +Bool +RRCrtcGammaSet (RRCrtcPtr crtc, + CARD16 *red, + CARD16 *green, + CARD16 *blue) +{ + Bool ret = TRUE; +#if RANDR_12_INTERFACE + ScreenPtr pScreen = crtc->pScreen; +#endif + + memcpy (crtc->gammaRed, red, crtc->gammaSize * sizeof (CARD16)); + memcpy (crtc->gammaGreen, green, crtc->gammaSize * sizeof (CARD16)); + memcpy (crtc->gammaBlue, blue, crtc->gammaSize * sizeof (CARD16)); +#if RANDR_12_INTERFACE + if (pScreen) + { + rrScrPriv(pScreen); + if (pScrPriv->rrCrtcSetGamma) + ret = (*pScrPriv->rrCrtcSetGamma) (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 + * in the RRCrtcRec + */ + +Bool +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) +{ + if (crtc->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; + } +} + +/* + * Set the size of the gamma table at server startup time + */ + +Bool +RRCrtcGammaSetSize (RRCrtcPtr crtc, + int size) +{ + CARD16 *gamma; + + if (size == crtc->gammaSize) + return TRUE; + if (size) + { + gamma = xalloc (size * 3 * sizeof (CARD16)); + if (!gamma) + return FALSE; + } + else + gamma = NULL; + if (crtc->gammaRed) + xfree (crtc->gammaRed); + crtc->gammaRed = gamma; + crtc->gammaGreen = gamma + size; + crtc->gammaBlue = gamma + size*2; + crtc->gammaSize = size; + return TRUE; +} + +/* + * Initialize crtc type + */ +Bool +RRCrtcInit (void) +{ + RRCrtcType = CreateNewResourceType (RRCrtcDestroyResource); + if (!RRCrtcType) + return FALSE; + RegisterResourceName (RRCrtcType, "CRTC"); + return TRUE; +} + +int +ProcRRGetCrtcInfo (ClientPtr client) +{ + REQUEST(xRRGetCrtcInfoReq); + xRRGetCrtcInfoReply rep; + RRCrtcPtr crtc; + CARD8 *extra; + unsigned long extraLen; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + RRModePtr mode; + RROutput *outputs; + RROutput *possible; + int i, j, k, n; + int width, height; + + REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq); + crtc = LookupCrtc(client, stuff->crtc, DixReadAccess); + + if (!crtc) + return RRErrorBase + BadRRCrtc; + + /* All crtcs must be associated with screens before client + * requests are processed + */ + pScreen = crtc->pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + 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.mode = mode ? mode->mode.id : 0; + rep.rotation = crtc->rotation; + rep.rotations = crtc->rotations; + rep.nOutput = crtc->numOutputs; + k = 0; + for (i = 0; i < pScrPriv->numOutputs; i++) + for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++) + if (pScrPriv->outputs[i]->crtcs[j] == crtc) + k++; + rep.nPossibleOutput = k; + + rep.length = rep.nOutput + rep.nPossibleOutput; + + extraLen = rep.length << 2; + if (extraLen) + { + extra = xalloc (extraLen); + if (!extra) + return BadAlloc; + } + else + extra = NULL; + + outputs = (RROutput *) extra; + possible = (RROutput *) (outputs + rep.nOutput); + + for (i = 0; i < crtc->numOutputs; i++) + { + outputs[i] = crtc->outputs[i]->id; + if (client->swapped) + swapl (&outputs[i], n); + } + k = 0; + for (i = 0; i < pScrPriv->numOutputs; i++) + for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++) + if (pScrPriv->outputs[i]->crtcs[j] == crtc) + { + possible[k] = pScrPriv->outputs[i]->id; + if (client->swapped) + swapl (&possible[k], n); + k++; + } + + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.timestamp, n); + swaps(&rep.x, n); + swaps(&rep.y, n); + swaps(&rep.width, n); + swaps(&rep.height, n); + swapl(&rep.mode, n); + swaps(&rep.rotation, n); + swaps(&rep.rotations, n); + swaps(&rep.nOutput, n); + swaps(&rep.nPossibleOutput, n); + } + WriteToClient(client, sizeof(xRRGetCrtcInfoReply), (char *)&rep); + if (extraLen) + { + WriteToClient (client, extraLen, (char *) extra); + xfree (extra); + } + + return client->noClientException; +} + +int +ProcRRSetCrtcConfig (ClientPtr client) +{ + REQUEST(xRRSetCrtcConfigReq); + xRRSetCrtcConfigReply rep; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + RRCrtcPtr crtc; + RRModePtr mode; + int numOutputs; + RROutputPtr *outputs = NULL; + RROutput *outputIds; + TimeStamp configTime; + TimeStamp time; + Rotation rotation; + int i, j; + + REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq); + numOutputs = (stuff->length - (SIZEOF (xRRSetCrtcConfigReq) >> 2)); + + 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; + } + if (numOutputs == 0) + return BadMatch; + } + if (numOutputs) + { + outputs = xalloc (numOutputs * sizeof (RROutputPtr)); + if (!outputs) + return BadAlloc; + } + else + outputs = NULL; + + outputIds = (RROutput *) (stuff + 1); + for (i = 0; i < numOutputs; i++) + { + outputs[i] = (RROutputPtr) LookupIDByType (outputIds[i], RROutputType); + if (!outputs[i]) + { + client->errorValue = outputIds[i]; + if (outputs) + xfree (outputs); + return RRErrorBase + BadRROutput; + } + /* 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); + return BadMatch; + } + /* validate mode for this output */ + for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++) + { + RRModePtr m = (j < outputs[i]->numModes ? + outputs[i]->modes[j] : + outputs[i]->userModes[j - outputs[i]->numModes]); + if (m == mode) + break; + } + if (j == outputs[i]->numModes + outputs[i]->numUserModes) + { + if (outputs) + xfree (outputs); + return BadMatch; + } + } + /* validate clones */ + for (i = 0; i < numOutputs; i++) + { + for (j = 0; j < numOutputs; j++) + { + int k; + if (i == j) + continue; + for (k = 0; k < outputs[i]->numClones; k++) + { + if (outputs[i]->clones[k] == outputs[j]) + break; + } + if (k == outputs[i]->numClones) + { + if (outputs) + xfree (outputs); + return BadMatch; + } + } + } + + pScreen = crtc->pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + time = ClientTimeToServerTime(stuff->timestamp); + configTime = ClientTimeToServerTime(stuff->configTimestamp); + + if (!pScrPriv) + { + time = currentTime; + rep.status = RRSetConfigFailed; + goto sendReply; + } + +#if 0 + /* + * if the client's config timestamp is not the same as the last config + * timestamp, then the config information isn't up-to-date and + * can't even be validated + */ + if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0) + { + rep.status = RRSetConfigInvalidConfigTime; + goto sendReply; + } +#endif + + /* + * Validate requested rotation + */ + rotation = (Rotation) stuff->rotation; + + /* test the rotation bits only! */ + switch (rotation & 0xf) { + case RR_Rotate_0: + case RR_Rotate_90: + case RR_Rotate_180: + case RR_Rotate_270: + break; + default: + /* + * Invalid rotation + */ + client->errorValue = stuff->rotation; + if (outputs) + xfree (outputs); + return BadValue; + } + + if (mode) + { + if ((~crtc->rotations) & rotation) + { + /* + * requested rotation or reflection not supported by screen + */ + client->errorValue = stuff->rotation; + if (outputs) + xfree (outputs); + return BadMatch; + } + +#ifdef RANDR_12_INTERFACE + /* + * 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 + */ + 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 (stuff->x + source_width > pScreen->width) + { + client->errorValue = stuff->x; + if (outputs) + xfree (outputs); + return BadValue; + } + + if (stuff->y + source_height > pScreen->height) + { + client->errorValue = stuff->y; + if (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; + goto sendReply; + } + #ifdef NXAGENT_SERVER /* Bug 21987 */ + pScrPriv->lastSetTime = time; + #endif + rep.status = RRSetConfigSuccess; + +sendReply: + if (outputs) + xfree (outputs); + + rep.type = X_Reply; + /* rep.status has already been filled in */ + rep.length = 0; + rep.sequenceNumber = client->sequence; + #ifndef NXAGENT_SERVER /* Bug 21987 */ + rep.newTimestamp = pScrPriv->lastConfigTime.milliseconds; + #else + rep.newTimestamp = pScrPriv->lastSetTime.milliseconds; + #endif + + if (client->swapped) + { + int n; + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.newTimestamp, n); + } + WriteToClient(client, sizeof(xRRSetCrtcConfigReply), (char *)&rep); + + return client->noClientException; +} + +int +ProcRRGetCrtcGammaSize (ClientPtr client) +{ + REQUEST(xRRGetCrtcGammaSizeReq); + xRRGetCrtcGammaSizeReply reply; + RRCrtcPtr crtc; + int n; + + REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq); + crtc = LookupCrtc (client, stuff->crtc, DixReadAccess); + if (!crtc) + return RRErrorBase + BadRRCrtc; + + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.length = 0; + reply.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; +} + +int +ProcRRGetCrtcGamma (ClientPtr client) +{ + REQUEST(xRRGetCrtcGammaReq); + xRRGetCrtcGammaReply reply; + RRCrtcPtr crtc; + int n; + unsigned long len; + char *extra; + + REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq); + crtc = LookupCrtc (client, stuff->crtc, DixReadAccess); + if (!crtc) + return RRErrorBase + BadRRCrtc; + + len = crtc->gammaSize * 3 * 2; + + if (crtc->gammaSize) { + extra = xalloc(len); + if (!extra) + return BadAlloc; + } + + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.length = (len + 3) >> 2; + reply.size = crtc->gammaSize; + if (client->swapped) { + swaps (&reply.sequenceNumber, n); + swapl (&reply.length, n); + swaps (&reply.size, n); + } + WriteToClient (client, sizeof (xRRGetCrtcGammaReply), (char *) &reply); + if (crtc->gammaSize) + { + memcpy(extra, crtc->gammaRed, len); + client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; + WriteSwappedDataToClient (client, len, extra); + xfree(extra); + } + return client->noClientException; +} + +int +ProcRRSetCrtcGamma (ClientPtr client) +{ + REQUEST(xRRSetCrtcGammaReq); + RRCrtcPtr crtc; + unsigned long len; + CARD16 *red, *green, *blue; + + REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq); + crtc = LookupCrtc (client, stuff->crtc, DixWriteAccess); + if (!crtc) + return RRErrorBase + BadRRCrtc; + + len = client->req_len - (sizeof (xRRSetCrtcGammaReq) >> 2); + if (len < (stuff->size * 3 + 1) >> 1) + return BadLength; + + if (stuff->size != crtc->gammaSize) + return BadMatch; + + red = (CARD16 *) (stuff + 1); + green = red + crtc->gammaSize; + blue = green + crtc->gammaSize; + + RRCrtcGammaSet (crtc, red, green, blue); + + return Success; +} + diff --git a/programs/Xserver/randr/rrcrtc.c.X.original b/programs/Xserver/randr/rrcrtc.c.X.original new file mode 100644 index 0000000..ec65a04 --- /dev/null +++ b/programs/Xserver/randr/rrcrtc.c.X.original @@ -0,0 +1,960 @@ +/* + * 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 "swaprep.h" +#include "registry.h" + +RESTYPE RRCrtcType; + +/* + * Notify the CRTC of some change + */ +void +RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged) +{ + ScreenPtr pScreen = crtc->pScreen; + + crtc->changed = TRUE; + if (pScreen) + { + rrScrPriv(pScreen); + + pScrPriv->changed = TRUE; + /* + * Send ConfigureNotify on any layout change + */ + if (layoutChanged) + pScrPriv->layoutChanged = TRUE; + } +} + +/* + * Create a CRTC + */ +RRCrtcPtr +RRCrtcCreate (ScreenPtr pScreen, void *devPrivate) +{ + RRCrtcPtr crtc; + RRCrtcPtr *crtcs; + rrScrPrivPtr pScrPriv; + + if (!RRInit()) + return NULL; + + pScrPriv = rrGetScrPriv(pScreen); + + /* make space for the crtc pointer */ + if (pScrPriv->numCrtcs) + crtcs = xrealloc (pScrPriv->crtcs, + (pScrPriv->numCrtcs + 1) * sizeof (RRCrtcPtr)); + else + crtcs = xalloc (sizeof (RRCrtcPtr)); + if (!crtcs) + return FALSE; + pScrPriv->crtcs = crtcs; + + crtc = xcalloc (1, sizeof (RRCrtcRec)); + if (!crtc) + return NULL; + crtc->id = FakeClientID (0); + crtc->pScreen = pScreen; + crtc->mode = NULL; + crtc->x = 0; + crtc->y = 0; + crtc->rotation = RR_Rotate_0; + crtc->rotations = RR_Rotate_0; + crtc->outputs = NULL; + crtc->numOutputs = 0; + crtc->gammaSize = 0; + crtc->gammaRed = crtc->gammaBlue = crtc->gammaGreen = NULL; + crtc->changed = FALSE; + crtc->devPrivate = devPrivate; + + if (!AddResource (crtc->id, RRCrtcType, (pointer) crtc)) + return NULL; + + /* attach the screen and crtc together */ + crtc->pScreen = pScreen; + pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc; + + return crtc; +} + +/* + * Set the allowed rotations on a CRTC + */ +void +RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations) +{ + crtc->rotations = rotations; +} + +/* + * Notify the extension that the Crtc has been reconfigured, + * the driver calls this whenever it has updated the mode + */ +Bool +RRCrtcNotify (RRCrtcPtr crtc, + RRModePtr mode, + int x, + int y, + Rotation rotation, + int numOutputs, + RROutputPtr *outputs) +{ + int i, j; + + /* + * Check to see if any of the new outputs were + * not in the old list and mark them as changed + */ + for (i = 0; i < numOutputs; i++) + { + for (j = 0; j < crtc->numOutputs; j++) + if (outputs[i] == crtc->outputs[j]) + break; + if (j == crtc->numOutputs) + { + outputs[i]->crtc = crtc; + RROutputChanged (outputs[i], FALSE); + RRCrtcChanged (crtc, FALSE); + } + } + /* + * Check to see if any of the old outputs are + * not in the new list and mark them as changed + */ + for (j = 0; j < crtc->numOutputs; j++) + { + for (i = 0; i < numOutputs; i++) + if (outputs[i] == crtc->outputs[j]) + break; + if (i == numOutputs) + { + if (crtc->outputs[j]->crtc == crtc) + crtc->outputs[j]->crtc = NULL; + RROutputChanged (crtc->outputs[j], FALSE); + RRCrtcChanged (crtc, FALSE); + } + } + /* + * Reallocate the crtc output array if necessary + */ + if (numOutputs != crtc->numOutputs) + { + RROutputPtr *newoutputs; + + if (numOutputs) + { + if (crtc->numOutputs) + newoutputs = xrealloc (crtc->outputs, + numOutputs * sizeof (RROutputPtr)); + else + newoutputs = xalloc (numOutputs * sizeof (RROutputPtr)); + if (!newoutputs) + return FALSE; + } + else + { + if (crtc->outputs) + xfree (crtc->outputs); + newoutputs = NULL; + } + crtc->outputs = newoutputs; + crtc->numOutputs = numOutputs; + } + /* + * Copy the new list of outputs into the crtc + */ + memcpy (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)); + /* + * Update remaining crtc fields + */ + if (mode != crtc->mode) + { + if (crtc->mode) + RRModeDestroy (crtc->mode); + crtc->mode = mode; + if (mode != NULL) + mode->refcnt++; + RRCrtcChanged (crtc, TRUE); + } + if (x != crtc->x) + { + crtc->x = x; + RRCrtcChanged (crtc, TRUE); + } + if (y != crtc->y) + { + crtc->y = y; + RRCrtcChanged (crtc, TRUE); + } + if (rotation != crtc->rotation) + { + crtc->rotation = rotation; + RRCrtcChanged (crtc, TRUE); + } + return TRUE; +} + +void +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; + } + WriteEventsToClient (client, 1, (xEvent *) &ce); +} + +static Bool +RRCrtcPendingProperties (RRCrtcPtr crtc) +{ + ScreenPtr pScreen = crtc->pScreen; + rrScrPriv(pScreen); + int o; + + for (o = 0; o < pScrPriv->numOutputs; o++) + { + RROutputPtr output = pScrPriv->outputs[o]; + if (output->crtc == crtc && output->pendingProperties) + return TRUE; + } + return FALSE; +} + +/* + * Request that the Crtc be reconfigured + */ +Bool +RRCrtcSet (RRCrtcPtr crtc, + RRModePtr mode, + int x, + int y, + Rotation rotation, + int numOutputs, + RROutputPtr *outputs) +{ + ScreenPtr pScreen = crtc->pScreen; + Bool ret = FALSE; + rrScrPriv(pScreen); + + /* See if nothing changed */ + if (crtc->mode == mode && + crtc->x == x && + crtc->y == y && + crtc->rotation == rotation && + crtc->numOutputs == numOutputs && + !memcmp (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)) && + !RRCrtcPendingProperties (crtc)) + { + ret = TRUE; + } + else + { +#if RANDR_12_INTERFACE + if (pScrPriv->rrCrtcSet) + { + ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y, + rotation, numOutputs, outputs); + } + else +#endif + { +#if RANDR_10_INTERFACE + if (pScrPriv->rrSetConfig) + { + RRScreenSize size; + RRScreenRate rate; + + if (!mode) + { + RRCrtcNotify (crtc, NULL, x, y, rotation, 0, NULL); + ret = TRUE; + } + else + { + size.width = mode->mode.width; + size.height = mode->mode.height; + if (outputs[0]->mmWidth && outputs[0]->mmHeight) + { + size.mmWidth = outputs[0]->mmWidth; + size.mmHeight = outputs[0]->mmHeight; + } + else + { + size.mmWidth = pScreen->mmWidth; + size.mmHeight = pScreen->mmHeight; + } + size.nRates = 1; + rate.rate = RRVerticalRefresh (&mode->mode); + size.pRates = &rate; + ret = (*pScrPriv->rrSetConfig) (pScreen, rotation, rate.rate, &size); + /* + * Old 1.0 interface tied screen size to mode size + */ + if (ret) + { + RRCrtcNotify (crtc, mode, x, y, rotation, 1, outputs); + RRScreenSizeNotify (pScreen); + } + } + } +#endif + } + if (ret) + { + int o; + RRTellChanged (pScreen); + + for (o = 0; o < numOutputs; o++) + RRPostPendingProperties (outputs[o]); + } + } + return ret; +} + +/* + * Destroy a Crtc at shutdown + */ +void +RRCrtcDestroy (RRCrtcPtr crtc) +{ + FreeResource (crtc->id, 0); +} + +static int +RRCrtcDestroyResource (pointer value, XID pid) +{ + RRCrtcPtr crtc = (RRCrtcPtr) value; + ScreenPtr pScreen = crtc->pScreen; + + if (pScreen) + { + rrScrPriv(pScreen); + int i; + + for (i = 0; i < pScrPriv->numCrtcs; i++) + { + if (pScrPriv->crtcs[i] == crtc) + { + memmove (pScrPriv->crtcs + i, pScrPriv->crtcs + i + 1, + (pScrPriv->numCrtcs - (i + 1)) * sizeof (RRCrtcPtr)); + --pScrPriv->numCrtcs; + break; + } + } + } + if (crtc->gammaRed) + xfree (crtc->gammaRed); + if (crtc->mode) + RRModeDestroy (crtc->mode); + xfree (crtc); + return 1; +} + +/* + * Request that the Crtc gamma be changed + */ + +Bool +RRCrtcGammaSet (RRCrtcPtr crtc, + CARD16 *red, + CARD16 *green, + CARD16 *blue) +{ + Bool ret = TRUE; +#if RANDR_12_INTERFACE + ScreenPtr pScreen = crtc->pScreen; +#endif + + memcpy (crtc->gammaRed, red, crtc->gammaSize * sizeof (CARD16)); + memcpy (crtc->gammaGreen, green, crtc->gammaSize * sizeof (CARD16)); + memcpy (crtc->gammaBlue, blue, crtc->gammaSize * sizeof (CARD16)); +#if RANDR_12_INTERFACE + if (pScreen) + { + rrScrPriv(pScreen); + if (pScrPriv->rrCrtcSetGamma) + ret = (*pScrPriv->rrCrtcSetGamma) (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 + * in the RRCrtcRec + */ + +Bool +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) +{ + if (crtc->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; + } +} + +/* + * Set the size of the gamma table at server startup time + */ + +Bool +RRCrtcGammaSetSize (RRCrtcPtr crtc, + int size) +{ + CARD16 *gamma; + + if (size == crtc->gammaSize) + return TRUE; + if (size) + { + gamma = xalloc (size * 3 * sizeof (CARD16)); + if (!gamma) + return FALSE; + } + else + gamma = NULL; + if (crtc->gammaRed) + xfree (crtc->gammaRed); + crtc->gammaRed = gamma; + crtc->gammaGreen = gamma + size; + crtc->gammaBlue = gamma + size*2; + crtc->gammaSize = size; + return TRUE; +} + +/* + * Initialize crtc type + */ +Bool +RRCrtcInit (void) +{ + RRCrtcType = CreateNewResourceType (RRCrtcDestroyResource); + if (!RRCrtcType) + return FALSE; + RegisterResourceName (RRCrtcType, "CRTC"); + return TRUE; +} + +int +ProcRRGetCrtcInfo (ClientPtr client) +{ + REQUEST(xRRGetCrtcInfoReq); + xRRGetCrtcInfoReply rep; + RRCrtcPtr crtc; + CARD8 *extra; + unsigned long extraLen; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + RRModePtr mode; + RROutput *outputs; + RROutput *possible; + int i, j, k, n; + int width, height; + + REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq); + crtc = LookupCrtc(client, stuff->crtc, DixReadAccess); + + if (!crtc) + return RRErrorBase + BadRRCrtc; + + /* All crtcs must be associated with screens before client + * requests are processed + */ + pScreen = crtc->pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + 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.mode = mode ? mode->mode.id : 0; + rep.rotation = crtc->rotation; + rep.rotations = crtc->rotations; + rep.nOutput = crtc->numOutputs; + k = 0; + for (i = 0; i < pScrPriv->numOutputs; i++) + for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++) + if (pScrPriv->outputs[i]->crtcs[j] == crtc) + k++; + rep.nPossibleOutput = k; + + rep.length = rep.nOutput + rep.nPossibleOutput; + + extraLen = rep.length << 2; + if (extraLen) + { + extra = xalloc (extraLen); + if (!extra) + return BadAlloc; + } + else + extra = NULL; + + outputs = (RROutput *) extra; + possible = (RROutput *) (outputs + rep.nOutput); + + for (i = 0; i < crtc->numOutputs; i++) + { + outputs[i] = crtc->outputs[i]->id; + if (client->swapped) + swapl (&outputs[i], n); + } + k = 0; + for (i = 0; i < pScrPriv->numOutputs; i++) + for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++) + if (pScrPriv->outputs[i]->crtcs[j] == crtc) + { + possible[k] = pScrPriv->outputs[i]->id; + if (client->swapped) + swapl (&possible[k], n); + k++; + } + + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.timestamp, n); + swaps(&rep.x, n); + swaps(&rep.y, n); + swaps(&rep.width, n); + swaps(&rep.height, n); + swapl(&rep.mode, n); + swaps(&rep.rotation, n); + swaps(&rep.rotations, n); + swaps(&rep.nOutput, n); + swaps(&rep.nPossibleOutput, n); + } + WriteToClient(client, sizeof(xRRGetCrtcInfoReply), (char *)&rep); + if (extraLen) + { + WriteToClient (client, extraLen, (char *) extra); + xfree (extra); + } + + return client->noClientException; +} + +int +ProcRRSetCrtcConfig (ClientPtr client) +{ + REQUEST(xRRSetCrtcConfigReq); + xRRSetCrtcConfigReply rep; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + RRCrtcPtr crtc; + RRModePtr mode; + int numOutputs; + RROutputPtr *outputs = NULL; + RROutput *outputIds; + TimeStamp configTime; + TimeStamp time; + Rotation rotation; + int i, j; + + REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq); + numOutputs = (stuff->length - (SIZEOF (xRRSetCrtcConfigReq) >> 2)); + + 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; + } + if (numOutputs == 0) + return BadMatch; + } + if (numOutputs) + { + outputs = xalloc (numOutputs * sizeof (RROutputPtr)); + if (!outputs) + return BadAlloc; + } + else + outputs = NULL; + + outputIds = (RROutput *) (stuff + 1); + for (i = 0; i < numOutputs; i++) + { + outputs[i] = (RROutputPtr) LookupIDByType (outputIds[i], RROutputType); + if (!outputs[i]) + { + client->errorValue = outputIds[i]; + if (outputs) + xfree (outputs); + return RRErrorBase + BadRROutput; + } + /* 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); + return BadMatch; + } + /* validate mode for this output */ + for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++) + { + RRModePtr m = (j < outputs[i]->numModes ? + outputs[i]->modes[j] : + outputs[i]->userModes[j - outputs[i]->numModes]); + if (m == mode) + break; + } + if (j == outputs[i]->numModes + outputs[i]->numUserModes) + { + if (outputs) + xfree (outputs); + return BadMatch; + } + } + /* validate clones */ + for (i = 0; i < numOutputs; i++) + { + for (j = 0; j < numOutputs; j++) + { + int k; + if (i == j) + continue; + for (k = 0; k < outputs[i]->numClones; k++) + { + if (outputs[i]->clones[k] == outputs[j]) + break; + } + if (k == outputs[i]->numClones) + { + if (outputs) + xfree (outputs); + return BadMatch; + } + } + } + + pScreen = crtc->pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + time = ClientTimeToServerTime(stuff->timestamp); + configTime = ClientTimeToServerTime(stuff->configTimestamp); + + if (!pScrPriv) + { + time = currentTime; + rep.status = RRSetConfigFailed; + goto sendReply; + } + +#if 0 + /* + * if the client's config timestamp is not the same as the last config + * timestamp, then the config information isn't up-to-date and + * can't even be validated + */ + if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0) + { + rep.status = RRSetConfigInvalidConfigTime; + goto sendReply; + } +#endif + + /* + * Validate requested rotation + */ + rotation = (Rotation) stuff->rotation; + + /* test the rotation bits only! */ + switch (rotation & 0xf) { + case RR_Rotate_0: + case RR_Rotate_90: + case RR_Rotate_180: + case RR_Rotate_270: + break; + default: + /* + * Invalid rotation + */ + client->errorValue = stuff->rotation; + if (outputs) + xfree (outputs); + return BadValue; + } + + if (mode) + { + if ((~crtc->rotations) & rotation) + { + /* + * requested rotation or reflection not supported by screen + */ + client->errorValue = stuff->rotation; + if (outputs) + xfree (outputs); + return BadMatch; + } + +#ifdef RANDR_12_INTERFACE + /* + * 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 + */ + 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 (stuff->x + source_width > pScreen->width) + { + client->errorValue = stuff->x; + if (outputs) + xfree (outputs); + return BadValue; + } + + if (stuff->y + source_height > pScreen->height) + { + client->errorValue = stuff->y; + if (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; + goto sendReply; + } + rep.status = RRSetConfigSuccess; + +sendReply: + if (outputs) + xfree (outputs); + + rep.type = X_Reply; + /* rep.status has already been filled in */ + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.newTimestamp = pScrPriv->lastConfigTime.milliseconds; + + if (client->swapped) + { + int n; + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.newTimestamp, n); + } + WriteToClient(client, sizeof(xRRSetCrtcConfigReply), (char *)&rep); + + return client->noClientException; +} + +int +ProcRRGetCrtcGammaSize (ClientPtr client) +{ + REQUEST(xRRGetCrtcGammaSizeReq); + xRRGetCrtcGammaSizeReply reply; + RRCrtcPtr crtc; + int n; + + REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq); + crtc = LookupCrtc (client, stuff->crtc, DixReadAccess); + if (!crtc) + return RRErrorBase + BadRRCrtc; + + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.length = 0; + reply.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; +} + +int +ProcRRGetCrtcGamma (ClientPtr client) +{ + REQUEST(xRRGetCrtcGammaReq); + xRRGetCrtcGammaReply reply; + RRCrtcPtr crtc; + int n; + unsigned long len; + char *extra; + + REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq); + crtc = LookupCrtc (client, stuff->crtc, DixReadAccess); + if (!crtc) + return RRErrorBase + BadRRCrtc; + + len = crtc->gammaSize * 3 * 2; + + if (crtc->gammaSize) { + extra = xalloc(len); + if (!extra) + return BadAlloc; + } + + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.length = (len + 3) >> 2; + reply.size = crtc->gammaSize; + if (client->swapped) { + swaps (&reply.sequenceNumber, n); + swapl (&reply.length, n); + swaps (&reply.size, n); + } + WriteToClient (client, sizeof (xRRGetCrtcGammaReply), (char *) &reply); + if (crtc->gammaSize) + { + memcpy(extra, crtc->gammaRed, len); + client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; + WriteSwappedDataToClient (client, len, extra); + xfree(extra); + } + return client->noClientException; +} + +int +ProcRRSetCrtcGamma (ClientPtr client) +{ + REQUEST(xRRSetCrtcGammaReq); + RRCrtcPtr crtc; + unsigned long len; + CARD16 *red, *green, *blue; + + REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq); + crtc = LookupCrtc (client, stuff->crtc, DixWriteAccess); + if (!crtc) + return RRErrorBase + BadRRCrtc; + + len = client->req_len - (sizeof (xRRSetCrtcGammaReq) >> 2); + if (len < (stuff->size * 3 + 1) >> 1) + return BadLength; + + if (stuff->size != crtc->gammaSize) + return BadMatch; + + red = (CARD16 *) (stuff + 1); + green = red + crtc->gammaSize; + blue = green + crtc->gammaSize; + + RRCrtcGammaSet (crtc, red, green, blue); + + return Success; +} + diff --git a/programs/Xserver/randr/rrdispatch.c b/programs/Xserver/randr/rrdispatch.c new file mode 100644 index 0000000..3d52b38 --- /dev/null +++ b/programs/Xserver/randr/rrdispatch.c @@ -0,0 +1,219 @@ +/* + * 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" + +#define SERVER_RANDR_MAJOR 1 +#define SERVER_RANDR_MINOR 2 + +Bool +RRClientKnowsRates (ClientPtr pClient) +{ + rrClientPriv(pClient); + + return (pRRClient->major_version > 1 || + (pRRClient->major_version == 1 && pRRClient->minor_version >= 1)); +} + +static int +ProcRRQueryVersion (ClientPtr client) +{ + xRRQueryVersionReply rep; + register int n; + 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 (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.majorVersion, n); + swapl(&rep.minorVersion, n); + } + WriteToClient(client, sizeof(xRRQueryVersionReply), (char *)&rep); + return (client->noClientException); +} + +static int +ProcRRSelectInput (ClientPtr client) +{ + REQUEST(xRRSelectInputReq); + rrClientPriv(client); + RRTimesPtr pTimes; + WindowPtr pWin; + RREventPtr pRREvent, *pHead; + XID clientResource; + int rc; + + REQUEST_SIZE_MATCH(xRRSelectInputReq); + #ifndef NXAGENT_SERVER + rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess); + #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); + + if (stuff->enable & (RRScreenChangeNotifyMask| + RRCrtcChangeNotifyMask| + RROutputChangeNotifyMask)) + { + ScreenPtr pScreen = pWin->drawable.pScreen; + rrScrPriv (pScreen); + + pRREvent = NULL; + if (pHead) + { + /* check for existing entry. */ + for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) + if (pRREvent->client == client) + break; + } + + if (!pRREvent) + { + /* build the entry */ + pRREvent = (RREventPtr) xalloc (sizeof (RREventRec)); + if (!pRREvent) + return BadAlloc; + pRREvent->next = 0; + pRREvent->client = client; + pRREvent->window = pWin; + pRREvent->mask = stuff->enable; + /* + * add a resource that will be deleted when + * the client goes away + */ + clientResource = FakeClientID (client->index); + pRREvent->clientResource = clientResource; + if (!AddResource (clientResource, RRClientType, (pointer)pRREvent)) + return BadAlloc; + /* + * create a resource to contain a pointer to the list + * of clients selecting input. This must be indirect as + * the list may be arbitrarily rearranged which cannot be + * done through the resource database. + */ + if (!pHead) + { + pHead = (RREventPtr *) xalloc (sizeof (RREventPtr)); + if (!pHead || + !AddResource (pWin->drawable.id, RREventType, (pointer)pHead)) + { + FreeResource (clientResource, RT_NONE); + return BadAlloc; + } + *pHead = 0; + } + pRREvent->next = *pHead; + *pHead = pRREvent; + } + /* + * Now see if the client needs an event + */ + if (pScrPriv && (pRREvent->mask & RRScreenChangeNotifyMask)) + { + pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum]; + if (CompareTimeStamps (pTimes->setTime, + pScrPriv->lastSetTime) != 0 || + CompareTimeStamps (pTimes->configTime, + pScrPriv->lastConfigTime) != 0) + { + RRDeliverScreenEvent (client, pWin, pScreen); + } + } + } + else if (stuff->enable == 0) + { + /* delete the interest */ + if (pHead) { + RREventPtr pNewRREvent = 0; + for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) { + if (pRREvent->client == client) + break; + pNewRREvent = pRREvent; + } + if (pRREvent) { + FreeResource (pRREvent->clientResource, RRClientType); + if (pNewRREvent) + pNewRREvent->next = pRREvent->next; + else + *pHead = pRREvent->next; + xfree (pRREvent); + } + } + } + else + { + client->errorValue = stuff->enable; + return BadValue; + } + return Success; +} + +int (*ProcRandrVector[RRNumberRequests])(ClientPtr) = { + ProcRRQueryVersion, /* 0 */ +/* we skip 1 to make old clients fail pretty immediately */ + NULL, /* 1 ProcRandrOldGetScreenInfo */ +/* V1.0 apps share the same set screen config request id */ + ProcRRSetScreenConfig, /* 2 */ + NULL, /* 3 ProcRandrOldScreenChangeSelectInput */ +/* 3 used to be ScreenChangeSelectInput; deprecated */ + ProcRRSelectInput, /* 4 */ + ProcRRGetScreenInfo, /* 5 */ +/* V1.2 additions */ + ProcRRGetScreenSizeRange, /* 6 */ + ProcRRSetScreenSize, /* 7 */ + ProcRRGetScreenResources, /* 8 */ + ProcRRGetOutputInfo, /* 9 */ + ProcRRListOutputProperties, /* 10 */ + ProcRRQueryOutputProperty, /* 11 */ + ProcRRConfigureOutputProperty, /* 12 */ + ProcRRChangeOutputProperty, /* 13 */ + ProcRRDeleteOutputProperty, /* 14 */ + ProcRRGetOutputProperty, /* 15 */ + ProcRRCreateMode, /* 16 */ + ProcRRDestroyMode, /* 17 */ + ProcRRAddOutputMode, /* 18 */ + ProcRRDeleteOutputMode, /* 19 */ + ProcRRGetCrtcInfo, /* 20 */ + ProcRRSetCrtcConfig, /* 21 */ + ProcRRGetCrtcGammaSize, /* 22 */ + ProcRRGetCrtcGamma, /* 23 */ + ProcRRSetCrtcGamma, /* 24 */ +}; + diff --git a/programs/Xserver/randr/rrdispatch.c.X.original b/programs/Xserver/randr/rrdispatch.c.X.original new file mode 100644 index 0000000..5525427 --- /dev/null +++ b/programs/Xserver/randr/rrdispatch.c.X.original @@ -0,0 +1,214 @@ +/* + * 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" + +#define SERVER_RANDR_MAJOR 1 +#define SERVER_RANDR_MINOR 2 + +Bool +RRClientKnowsRates (ClientPtr pClient) +{ + rrClientPriv(pClient); + + return (pRRClient->major_version > 1 || + (pRRClient->major_version == 1 && pRRClient->minor_version >= 1)); +} + +static int +ProcRRQueryVersion (ClientPtr client) +{ + xRRQueryVersionReply rep; + register int n; + 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 (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.majorVersion, n); + swapl(&rep.minorVersion, n); + } + WriteToClient(client, sizeof(xRRQueryVersionReply), (char *)&rep); + return (client->noClientException); +} + +static int +ProcRRSelectInput (ClientPtr client) +{ + REQUEST(xRRSelectInputReq); + rrClientPriv(client); + RRTimesPtr pTimes; + WindowPtr pWin; + RREventPtr pRREvent, *pHead; + XID clientResource; + int rc; + + REQUEST_SIZE_MATCH(xRRSelectInputReq); + rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess); + if (rc != Success) + return rc; + pHead = (RREventPtr *)SecurityLookupIDByType(client, + pWin->drawable.id, RREventType, + DixWriteAccess); + + if (stuff->enable & (RRScreenChangeNotifyMask| + RRCrtcChangeNotifyMask| + RROutputChangeNotifyMask)) + { + ScreenPtr pScreen = pWin->drawable.pScreen; + rrScrPriv (pScreen); + + pRREvent = NULL; + if (pHead) + { + /* check for existing entry. */ + for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) + if (pRREvent->client == client) + break; + } + + if (!pRREvent) + { + /* build the entry */ + pRREvent = (RREventPtr) xalloc (sizeof (RREventRec)); + if (!pRREvent) + return BadAlloc; + pRREvent->next = 0; + pRREvent->client = client; + pRREvent->window = pWin; + pRREvent->mask = stuff->enable; + /* + * add a resource that will be deleted when + * the client goes away + */ + clientResource = FakeClientID (client->index); + pRREvent->clientResource = clientResource; + if (!AddResource (clientResource, RRClientType, (pointer)pRREvent)) + return BadAlloc; + /* + * create a resource to contain a pointer to the list + * of clients selecting input. This must be indirect as + * the list may be arbitrarily rearranged which cannot be + * done through the resource database. + */ + if (!pHead) + { + pHead = (RREventPtr *) xalloc (sizeof (RREventPtr)); + if (!pHead || + !AddResource (pWin->drawable.id, RREventType, (pointer)pHead)) + { + FreeResource (clientResource, RT_NONE); + return BadAlloc; + } + *pHead = 0; + } + pRREvent->next = *pHead; + *pHead = pRREvent; + } + /* + * Now see if the client needs an event + */ + if (pScrPriv && (pRREvent->mask & RRScreenChangeNotifyMask)) + { + pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum]; + if (CompareTimeStamps (pTimes->setTime, + pScrPriv->lastSetTime) != 0 || + CompareTimeStamps (pTimes->configTime, + pScrPriv->lastConfigTime) != 0) + { + RRDeliverScreenEvent (client, pWin, pScreen); + } + } + } + else if (stuff->enable == 0) + { + /* delete the interest */ + if (pHead) { + RREventPtr pNewRREvent = 0; + for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) { + if (pRREvent->client == client) + break; + pNewRREvent = pRREvent; + } + if (pRREvent) { + FreeResource (pRREvent->clientResource, RRClientType); + if (pNewRREvent) + pNewRREvent->next = pRREvent->next; + else + *pHead = pRREvent->next; + xfree (pRREvent); + } + } + } + else + { + client->errorValue = stuff->enable; + return BadValue; + } + return Success; +} + +int (*ProcRandrVector[RRNumberRequests])(ClientPtr) = { + ProcRRQueryVersion, /* 0 */ +/* we skip 1 to make old clients fail pretty immediately */ + NULL, /* 1 ProcRandrOldGetScreenInfo */ +/* V1.0 apps share the same set screen config request id */ + ProcRRSetScreenConfig, /* 2 */ + NULL, /* 3 ProcRandrOldScreenChangeSelectInput */ +/* 3 used to be ScreenChangeSelectInput; deprecated */ + ProcRRSelectInput, /* 4 */ + ProcRRGetScreenInfo, /* 5 */ +/* V1.2 additions */ + ProcRRGetScreenSizeRange, /* 6 */ + ProcRRSetScreenSize, /* 7 */ + ProcRRGetScreenResources, /* 8 */ + ProcRRGetOutputInfo, /* 9 */ + ProcRRListOutputProperties, /* 10 */ + ProcRRQueryOutputProperty, /* 11 */ + ProcRRConfigureOutputProperty, /* 12 */ + ProcRRChangeOutputProperty, /* 13 */ + ProcRRDeleteOutputProperty, /* 14 */ + ProcRRGetOutputProperty, /* 15 */ + ProcRRCreateMode, /* 16 */ + ProcRRDestroyMode, /* 17 */ + ProcRRAddOutputMode, /* 18 */ + ProcRRDeleteOutputMode, /* 19 */ + ProcRRGetCrtcInfo, /* 20 */ + ProcRRSetCrtcConfig, /* 21 */ + ProcRRGetCrtcGammaSize, /* 22 */ + ProcRRGetCrtcGamma, /* 23 */ + ProcRRSetCrtcGamma, /* 24 */ +}; + diff --git a/programs/Xserver/randr/rrinfo.c b/programs/Xserver/randr/rrinfo.c new file mode 100644 index 0000000..7e77d39 --- /dev/null +++ b/programs/Xserver/randr/rrinfo.c @@ -0,0 +1,335 @@ +/* + * 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" + +#ifdef RANDR_10_INTERFACE +static RRModePtr +RROldModeAdd (RROutputPtr output, RRScreenSizePtr size, int refresh) +{ + ScreenPtr pScreen = output->pScreen; + rrScrPriv(pScreen); + xRRModeInfo modeInfo; + char name[100]; + RRModePtr mode; + int i; + RRModePtr *modes; + + memset (&modeInfo, '\0', sizeof (modeInfo)); + sprintf (name, "%dx%d", size->width, size->height); + + modeInfo.width = size->width; + modeInfo.height = size->height; + modeInfo.hTotal = size->width; + modeInfo.vTotal = size->height; + modeInfo.dotClock = ((CARD32) size->width * (CARD32) size->height * + (CARD32) refresh); + modeInfo.nameLength = strlen (name); + mode = RRModeGet (&modeInfo, name); + if (!mode) + return NULL; + for (i = 0; i < output->numModes; i++) + if (output->modes[i] == mode) + { + RRModeDestroy (mode); + return mode; + } + + if (output->numModes) + modes = xrealloc (output->modes, + (output->numModes + 1) * sizeof (RRModePtr)); + else + modes = xalloc (sizeof (RRModePtr)); + if (!modes) + { + RRModeDestroy (mode); + FreeResource (mode->mode.id, 0); + return NULL; + } + modes[output->numModes++] = mode; + output->modes = modes; + output->changed = TRUE; + pScrPriv->changed = TRUE; + pScrPriv->configChanged = TRUE; + return mode; +} + +static void +RRScanOldConfig (ScreenPtr pScreen, Rotation rotations) +{ + rrScrPriv(pScreen); + RROutputPtr output; + RRCrtcPtr crtc; + RRModePtr mode, newMode = NULL; + int i; + CARD16 minWidth = MAXSHORT, minHeight = MAXSHORT; + CARD16 maxWidth = 0, maxHeight = 0; + + /* + * First time through, create a crtc and output and hook + * them together + */ + if (pScrPriv->numOutputs == 0 && + pScrPriv->numCrtcs == 0) + { + crtc = RRCrtcCreate (pScreen, NULL); + if (!crtc) + return; + output = RROutputCreate (pScreen, "default", 7, NULL); + if (!output) + return; + RROutputSetCrtcs (output, &crtc, 1); + RROutputSetConnection (output, RR_Connected); +#ifdef RENDER + RROutputSetSubpixelOrder (output, PictureGetSubpixelOrder (pScreen)); +#endif + } + + output = pScrPriv->outputs[0]; + if (!output) + return; + crtc = pScrPriv->crtcs[0]; + if (!crtc) + return; + + /* check rotations */ + if (rotations != crtc->rotations) + { + crtc->rotations = rotations; + crtc->changed = TRUE; + pScrPriv->changed = TRUE; + } + + /* regenerate mode list */ + for (i = 0; i < pScrPriv->nSizes; i++) + { + RRScreenSizePtr size = &pScrPriv->pSizes[i]; + int r; + + if (size->nRates) + { + for (r = 0; r < size->nRates; r++) + { + mode = RROldModeAdd (output, size, size->pRates[r].rate); + if (i == pScrPriv->size && + size->pRates[r].rate == pScrPriv->rate) + { + newMode = mode; + } + } + xfree (size->pRates); + } + else + { + mode = RROldModeAdd (output, size, 0); + if (i == pScrPriv->size) + newMode = mode; + } + } + if (pScrPriv->nSizes) + xfree (pScrPriv->pSizes); + pScrPriv->pSizes = NULL; + pScrPriv->nSizes = 0; + + /* find size bounds */ + for (i = 0; i < output->numModes + output->numUserModes; i++) + { + RRModePtr mode = (i < output->numModes ? + output->modes[i] : + output->userModes[i-output->numModes]); + CARD16 width = mode->mode.width; + CARD16 height = mode->mode.height; + + if (width < minWidth) minWidth = width; + if (width > maxWidth) maxWidth = width; + if (height < minHeight) minHeight = height; + if (height > maxHeight) maxHeight = height; + } + + RRScreenSetSizeRange (pScreen, minWidth, minHeight, maxWidth, maxHeight); + + /* notice current mode */ + if (newMode) + RRCrtcNotify (crtc, newMode, 0, 0, pScrPriv->rotation, + 1, &output); +} +#endif + +/* + * Poll the driver for changed information + */ +Bool +RRGetInfo (ScreenPtr pScreen) +{ + rrScrPriv (pScreen); + Rotation rotations; + int i; + + for (i = 0; i < pScrPriv->numOutputs; i++) + pScrPriv->outputs[i]->changed = FALSE; + for (i = 0; i < pScrPriv->numCrtcs; i++) + pScrPriv->crtcs[i]->changed = FALSE; + + rotations = 0; + pScrPriv->changed = FALSE; + pScrPriv->configChanged = FALSE; + + if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations)) + return FALSE; + +#if RANDR_10_INTERFACE + if (pScrPriv->nSizes) + RRScanOldConfig (pScreen, rotations); +#endif + RRTellChanged (pScreen); + return TRUE; +} + +/* + * Register the range of sizes for the screen + */ +void +RRScreenSetSizeRange (ScreenPtr pScreen, + CARD16 minWidth, + CARD16 minHeight, + CARD16 maxWidth, + CARD16 maxHeight) +{ + rrScrPriv (pScreen); + + if (!pScrPriv) + return; + if (pScrPriv->minWidth == minWidth && pScrPriv->minHeight == minHeight && + pScrPriv->maxWidth == maxWidth && pScrPriv->maxHeight == maxHeight) + { + return; + } + + pScrPriv->minWidth = minWidth; + pScrPriv->minHeight = minHeight; + pScrPriv->maxWidth = maxWidth; + pScrPriv->maxHeight = maxHeight; + pScrPriv->changed = TRUE; + pScrPriv->configChanged = TRUE; +} + +#ifdef RANDR_10_INTERFACE +static Bool +RRScreenSizeMatches (RRScreenSizePtr a, + RRScreenSizePtr b) +{ + if (a->width != b->width) + return FALSE; + if (a->height != b->height) + return FALSE; + if (a->mmWidth != b->mmWidth) + return FALSE; + if (a->mmHeight != b->mmHeight) + return FALSE; + return TRUE; +} + +RRScreenSizePtr +RRRegisterSize (ScreenPtr pScreen, + short width, + short height, + short mmWidth, + short mmHeight) +{ + rrScrPriv (pScreen); + int i; + RRScreenSize tmp; + RRScreenSizePtr pNew; + + if (!pScrPriv) + return 0; + + tmp.id = 0; + tmp.width = width; + tmp.height= height; + tmp.mmWidth = mmWidth; + tmp.mmHeight = mmHeight; + tmp.pRates = 0; + tmp.nRates = 0; + for (i = 0; i < pScrPriv->nSizes; i++) + if (RRScreenSizeMatches (&tmp, &pScrPriv->pSizes[i])) + return &pScrPriv->pSizes[i]; + pNew = xrealloc (pScrPriv->pSizes, + (pScrPriv->nSizes + 1) * sizeof (RRScreenSize)); + if (!pNew) + return 0; + pNew[pScrPriv->nSizes++] = tmp; + pScrPriv->pSizes = pNew; + return &pNew[pScrPriv->nSizes-1]; +} + +Bool RRRegisterRate (ScreenPtr pScreen, + RRScreenSizePtr pSize, + int rate) +{ + rrScrPriv(pScreen); + int i; + RRScreenRatePtr pNew, pRate; + + if (!pScrPriv) + return FALSE; + + for (i = 0; i < pSize->nRates; i++) + if (pSize->pRates[i].rate == rate) + return TRUE; + + pNew = xrealloc (pSize->pRates, + (pSize->nRates + 1) * sizeof (RRScreenRate)); + if (!pNew) + return FALSE; + pRate = &pNew[pSize->nRates++]; + pRate->rate = rate; + pSize->pRates = pNew; + return TRUE; +} + +Rotation +RRGetRotation(ScreenPtr pScreen) +{ + RROutputPtr output = RRFirstOutput (pScreen); + + if (!output) + return RR_Rotate_0; + + return output->crtc->rotation; +} + +void +RRSetCurrentConfig (ScreenPtr pScreen, + Rotation rotation, + int rate, + RRScreenSizePtr pSize) +{ + rrScrPriv (pScreen); + + if (!pScrPriv) + return; + pScrPriv->size = pSize - pScrPriv->pSizes; + pScrPriv->rotation = rotation; + pScrPriv->rate = rate; +} +#endif diff --git a/programs/Xserver/randr/rrmode.c b/programs/Xserver/randr/rrmode.c new file mode 100644 index 0000000..62c0148 --- /dev/null +++ b/programs/Xserver/randr/rrmode.c @@ -0,0 +1,420 @@ +/* + * 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. + */ + +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */ +/* */ +/* NX-X11, NX protocol compression and NX extensions to this software */ +/* are copyright of NoMachine. Redistribution and use of the present */ +/* software is allowed according to terms specified in the file LICENSE */ +/* which comes in the source distribution. */ +/* */ +/* Check http://www.nomachine.com/licensing.html for applicability. */ +/* */ +/* NX and NoMachine are trademarks of Medialogic S.p.A. */ +/* */ +/* All rights reserved. */ +/* */ +/**************************************************************************/ + +#include "randrstr.h" +#include "registry.h" + +RESTYPE RRModeType; + +static Bool +RRModeEqual (xRRModeInfo *a, xRRModeInfo *b) +{ + if (a->width != b->width) return FALSE; + if (a->height != b->height) return FALSE; + if (a->dotClock != b->dotClock) return FALSE; + if (a->hSyncStart != b->hSyncStart) return FALSE; + if (a->hSyncEnd != b->hSyncEnd) return FALSE; + if (a->hTotal != b->hTotal) return FALSE; + if (a->hSkew != b->hSkew) return FALSE; + if (a->vSyncStart != b->vSyncStart) return FALSE; + if (a->vSyncEnd != b->vSyncEnd) return FALSE; + if (a->vTotal != b->vTotal) return FALSE; + if (a->nameLength != b->nameLength) return FALSE; + if (a->modeFlags != b->modeFlags) return FALSE; + return TRUE; +} + +/* + * Keep a list so it's easy to find modes in the resource database. + */ +static int num_modes; +static RRModePtr *modes; + +static RRModePtr +RRModeCreate (xRRModeInfo *modeInfo, + const char *name, + ScreenPtr userScreen) +{ + RRModePtr mode, *newModes; + + if (!RRInit ()) + return NULL; + + mode = xalloc (sizeof (RRModeRec) + modeInfo->nameLength + 1); + if (!mode) + return NULL; + mode->refcnt = 1; + mode->mode = *modeInfo; + mode->name = (char *) (mode + 1); + memcpy (mode->name, name, modeInfo->nameLength); + mode->name[modeInfo->nameLength] = '\0'; + mode->userScreen = userScreen; + + if (num_modes) + newModes = xrealloc (modes, (num_modes + 1) * sizeof (RRModePtr)); + else + newModes = xalloc (sizeof (RRModePtr)); + + if (!newModes) + { + xfree (mode); + return NULL; + } + + mode->mode.id = FakeClientID(0); + if (!AddResource (mode->mode.id, RRModeType, (pointer) mode)) + return NULL; + modes = newModes; + modes[num_modes++] = mode; + + /* + * give the caller a reference to this mode + */ + ++mode->refcnt; + return mode; +} + +static RRModePtr +RRModeFindByName (const char *name, + CARD16 nameLength) +{ + int i; + RRModePtr mode; + + for (i = 0; i < num_modes; i++) + { + mode = modes[i]; + if (mode->mode.nameLength == nameLength && + !memcmp (name, mode->name, nameLength)) + { + return mode; + } + } + return NULL; +} + +RRModePtr +RRModeGet (xRRModeInfo *modeInfo, + const char *name) +{ + int i; + + for (i = 0; i < num_modes; i++) + { + RRModePtr mode = modes[i]; + if (RRModeEqual (&mode->mode, modeInfo) && + !memcmp (name, mode->name, modeInfo->nameLength)) + { + ++mode->refcnt; + return mode; + } + } + + return RRModeCreate (modeInfo, name, NULL); +} + +static RRModePtr +RRModeCreateUser (ScreenPtr pScreen, + xRRModeInfo *modeInfo, + const char *name, + int *error) +{ + RRModePtr mode; + + mode = RRModeFindByName (name, modeInfo->nameLength); + if (mode) + { + *error = BadName; + return NULL; + } + + mode = RRModeCreate (modeInfo, name, pScreen); + if (!mode) + { + *error = BadAlloc; + return NULL; + } + *error = Success; + return mode; +} + +RRModePtr * +RRModesForScreen (ScreenPtr pScreen, int *num_ret) +{ + rrScrPriv(pScreen); + int o, c, m; + RRModePtr *screen_modes; + int num_screen_modes = 0; + + screen_modes = xalloc ((num_modes ? num_modes : 1) * sizeof (RRModePtr)); + if (!screen_modes) + return NULL; + + /* + * Add modes from all outputs + */ + for (o = 0; o < pScrPriv->numOutputs; o++) + { + RROutputPtr output = pScrPriv->outputs[o]; + int m, n; + + for (m = 0; m < output->numModes + output->numUserModes; m++) + { + RRModePtr mode = (m < output->numModes ? + output->modes[m] : + output->userModes[m-output->numModes]); + for (n = 0; n < num_screen_modes; n++) + if (screen_modes[n] == mode) + break; + if (n == num_screen_modes) + screen_modes[num_screen_modes++] = mode; + } + } + /* + * Add modes from all crtcs. The goal is to + * make sure all available and active modes + * are visible to the client + */ + for (c = 0; c < pScrPriv->numCrtcs; c++) + { + RRCrtcPtr crtc = pScrPriv->crtcs[c]; + RRModePtr mode = crtc->mode; + int n; + + if (!mode) continue; + for (n = 0; n < num_screen_modes; n++) + if (screen_modes[n] == mode) + break; + if (n == num_screen_modes) + screen_modes[num_screen_modes++] = mode; + } + /* + * Add all user modes for this screen + */ + for (m = 0; m < num_modes; m++) + { + RRModePtr mode = modes[m]; + int n; + + if (mode->userScreen != pScreen) + continue; + for (n = 0; n < num_screen_modes; n++) + if (screen_modes[n] == mode) + break; + if (n == num_screen_modes) + screen_modes[num_screen_modes++] = mode; + } + + *num_ret = num_screen_modes; + return screen_modes; +} + +void +RRModeDestroy (RRModePtr mode) +{ + int m; + + if (--mode->refcnt > 0) + return; + for (m = 0; m < num_modes; m++) + { + if (modes[m] == mode) + { + memmove (modes + m, modes + m + 1, + (num_modes - m - 1) * sizeof (RRModePtr)); + num_modes--; + if (!num_modes) + { + xfree (modes); + modes = NULL; + } + break; + } + } + + xfree (mode); +} + +static int +RRModeDestroyResource (pointer value, XID pid) +{ + RRModeDestroy ((RRModePtr) value); + return 1; +} + +Bool +RRModeInit (void) +{ + assert (num_modes == 0); + assert (modes == NULL); + RRModeType = CreateNewResourceType (RRModeDestroyResource); + if (!RRModeType) + return FALSE; + RegisterResourceName (RRModeType, "MODE"); + return TRUE; +} + +int +ProcRRCreateMode (ClientPtr client) +{ + REQUEST(xRRCreateModeReq); + xRRCreateModeReply rep; + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + xRRModeInfo *modeInfo; + long units_after; + char *name; + int error, rc; + RRModePtr mode; + + REQUEST_AT_LEAST_SIZE (xRRCreateModeReq); + #ifndef NXAGENT_SERVER + rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); + #else + pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess); + rc = pWin ? Success : BadWindow; + #endif + if (rc != Success) + return rc; + + pScreen = pWin->drawable.pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + modeInfo = &stuff->modeInfo; + name = (char *) (stuff + 1); + units_after = (stuff->length - (sizeof (xRRCreateModeReq) >> 2)); + + /* check to make sure requested name fits within the data provided */ + if ((int) (modeInfo->nameLength + 3) >> 2 > 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; + if (client->swapped) + { + int n; + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.mode, n); + } + WriteToClient(client, sizeof(xRRCreateModeReply), (char *)&rep); + + return client->noClientException; +} + +int +ProcRRDestroyMode (ClientPtr client) +{ + REQUEST(xRRDestroyModeReq); + RRModePtr mode; + + REQUEST_SIZE_MATCH(xRRDestroyModeReq); + mode = LookupIDByType (stuff->mode, RRModeType); + if (!mode) + { + client->errorValue = stuff->mode; + return RRErrorBase + BadRRMode; + } + if (!mode->userScreen) + return BadMatch; + if (mode->refcnt > 1) + return BadAccess; + FreeResource (stuff->mode, 0); + return Success; +} + +int +ProcRRAddOutputMode (ClientPtr client) +{ + REQUEST(xRRAddOutputModeReq); + RRModePtr mode; + 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; + } + + return RROutputAddUserMode (output, mode); +} + +int +ProcRRDeleteOutputMode (ClientPtr client) +{ + REQUEST(xRRDeleteOutputModeReq); + RRModePtr mode; + 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; + } + + return RROutputDeleteUserMode (output, mode); +} diff --git a/programs/Xserver/randr/rrmode.c.NX.original b/programs/Xserver/randr/rrmode.c.NX.original new file mode 100644 index 0000000..62c0148 --- /dev/null +++ b/programs/Xserver/randr/rrmode.c.NX.original @@ -0,0 +1,420 @@ +/* + * 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. + */ + +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */ +/* */ +/* NX-X11, NX protocol compression and NX extensions to this software */ +/* are copyright of NoMachine. Redistribution and use of the present */ +/* software is allowed according to terms specified in the file LICENSE */ +/* which comes in the source distribution. */ +/* */ +/* Check http://www.nomachine.com/licensing.html for applicability. */ +/* */ +/* NX and NoMachine are trademarks of Medialogic S.p.A. */ +/* */ +/* All rights reserved. */ +/* */ +/**************************************************************************/ + +#include "randrstr.h" +#include "registry.h" + +RESTYPE RRModeType; + +static Bool +RRModeEqual (xRRModeInfo *a, xRRModeInfo *b) +{ + if (a->width != b->width) return FALSE; + if (a->height != b->height) return FALSE; + if (a->dotClock != b->dotClock) return FALSE; + if (a->hSyncStart != b->hSyncStart) return FALSE; + if (a->hSyncEnd != b->hSyncEnd) return FALSE; + if (a->hTotal != b->hTotal) return FALSE; + if (a->hSkew != b->hSkew) return FALSE; + if (a->vSyncStart != b->vSyncStart) return FALSE; + if (a->vSyncEnd != b->vSyncEnd) return FALSE; + if (a->vTotal != b->vTotal) return FALSE; + if (a->nameLength != b->nameLength) return FALSE; + if (a->modeFlags != b->modeFlags) return FALSE; + return TRUE; +} + +/* + * Keep a list so it's easy to find modes in the resource database. + */ +static int num_modes; +static RRModePtr *modes; + +static RRModePtr +RRModeCreate (xRRModeInfo *modeInfo, + const char *name, + ScreenPtr userScreen) +{ + RRModePtr mode, *newModes; + + if (!RRInit ()) + return NULL; + + mode = xalloc (sizeof (RRModeRec) + modeInfo->nameLength + 1); + if (!mode) + return NULL; + mode->refcnt = 1; + mode->mode = *modeInfo; + mode->name = (char *) (mode + 1); + memcpy (mode->name, name, modeInfo->nameLength); + mode->name[modeInfo->nameLength] = '\0'; + mode->userScreen = userScreen; + + if (num_modes) + newModes = xrealloc (modes, (num_modes + 1) * sizeof (RRModePtr)); + else + newModes = xalloc (sizeof (RRModePtr)); + + if (!newModes) + { + xfree (mode); + return NULL; + } + + mode->mode.id = FakeClientID(0); + if (!AddResource (mode->mode.id, RRModeType, (pointer) mode)) + return NULL; + modes = newModes; + modes[num_modes++] = mode; + + /* + * give the caller a reference to this mode + */ + ++mode->refcnt; + return mode; +} + +static RRModePtr +RRModeFindByName (const char *name, + CARD16 nameLength) +{ + int i; + RRModePtr mode; + + for (i = 0; i < num_modes; i++) + { + mode = modes[i]; + if (mode->mode.nameLength == nameLength && + !memcmp (name, mode->name, nameLength)) + { + return mode; + } + } + return NULL; +} + +RRModePtr +RRModeGet (xRRModeInfo *modeInfo, + const char *name) +{ + int i; + + for (i = 0; i < num_modes; i++) + { + RRModePtr mode = modes[i]; + if (RRModeEqual (&mode->mode, modeInfo) && + !memcmp (name, mode->name, modeInfo->nameLength)) + { + ++mode->refcnt; + return mode; + } + } + + return RRModeCreate (modeInfo, name, NULL); +} + +static RRModePtr +RRModeCreateUser (ScreenPtr pScreen, + xRRModeInfo *modeInfo, + const char *name, + int *error) +{ + RRModePtr mode; + + mode = RRModeFindByName (name, modeInfo->nameLength); + if (mode) + { + *error = BadName; + return NULL; + } + + mode = RRModeCreate (modeInfo, name, pScreen); + if (!mode) + { + *error = BadAlloc; + return NULL; + } + *error = Success; + return mode; +} + +RRModePtr * +RRModesForScreen (ScreenPtr pScreen, int *num_ret) +{ + rrScrPriv(pScreen); + int o, c, m; + RRModePtr *screen_modes; + int num_screen_modes = 0; + + screen_modes = xalloc ((num_modes ? num_modes : 1) * sizeof (RRModePtr)); + if (!screen_modes) + return NULL; + + /* + * Add modes from all outputs + */ + for (o = 0; o < pScrPriv->numOutputs; o++) + { + RROutputPtr output = pScrPriv->outputs[o]; + int m, n; + + for (m = 0; m < output->numModes + output->numUserModes; m++) + { + RRModePtr mode = (m < output->numModes ? + output->modes[m] : + output->userModes[m-output->numModes]); + for (n = 0; n < num_screen_modes; n++) + if (screen_modes[n] == mode) + break; + if (n == num_screen_modes) + screen_modes[num_screen_modes++] = mode; + } + } + /* + * Add modes from all crtcs. The goal is to + * make sure all available and active modes + * are visible to the client + */ + for (c = 0; c < pScrPriv->numCrtcs; c++) + { + RRCrtcPtr crtc = pScrPriv->crtcs[c]; + RRModePtr mode = crtc->mode; + int n; + + if (!mode) continue; + for (n = 0; n < num_screen_modes; n++) + if (screen_modes[n] == mode) + break; + if (n == num_screen_modes) + screen_modes[num_screen_modes++] = mode; + } + /* + * Add all user modes for this screen + */ + for (m = 0; m < num_modes; m++) + { + RRModePtr mode = modes[m]; + int n; + + if (mode->userScreen != pScreen) + continue; + for (n = 0; n < num_screen_modes; n++) + if (screen_modes[n] == mode) + break; + if (n == num_screen_modes) + screen_modes[num_screen_modes++] = mode; + } + + *num_ret = num_screen_modes; + return screen_modes; +} + +void +RRModeDestroy (RRModePtr mode) +{ + int m; + + if (--mode->refcnt > 0) + return; + for (m = 0; m < num_modes; m++) + { + if (modes[m] == mode) + { + memmove (modes + m, modes + m + 1, + (num_modes - m - 1) * sizeof (RRModePtr)); + num_modes--; + if (!num_modes) + { + xfree (modes); + modes = NULL; + } + break; + } + } + + xfree (mode); +} + +static int +RRModeDestroyResource (pointer value, XID pid) +{ + RRModeDestroy ((RRModePtr) value); + return 1; +} + +Bool +RRModeInit (void) +{ + assert (num_modes == 0); + assert (modes == NULL); + RRModeType = CreateNewResourceType (RRModeDestroyResource); + if (!RRModeType) + return FALSE; + RegisterResourceName (RRModeType, "MODE"); + return TRUE; +} + +int +ProcRRCreateMode (ClientPtr client) +{ + REQUEST(xRRCreateModeReq); + xRRCreateModeReply rep; + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + xRRModeInfo *modeInfo; + long units_after; + char *name; + int error, rc; + RRModePtr mode; + + REQUEST_AT_LEAST_SIZE (xRRCreateModeReq); + #ifndef NXAGENT_SERVER + rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); + #else + pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess); + rc = pWin ? Success : BadWindow; + #endif + if (rc != Success) + return rc; + + pScreen = pWin->drawable.pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + modeInfo = &stuff->modeInfo; + name = (char *) (stuff + 1); + units_after = (stuff->length - (sizeof (xRRCreateModeReq) >> 2)); + + /* check to make sure requested name fits within the data provided */ + if ((int) (modeInfo->nameLength + 3) >> 2 > 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; + if (client->swapped) + { + int n; + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.mode, n); + } + WriteToClient(client, sizeof(xRRCreateModeReply), (char *)&rep); + + return client->noClientException; +} + +int +ProcRRDestroyMode (ClientPtr client) +{ + REQUEST(xRRDestroyModeReq); + RRModePtr mode; + + REQUEST_SIZE_MATCH(xRRDestroyModeReq); + mode = LookupIDByType (stuff->mode, RRModeType); + if (!mode) + { + client->errorValue = stuff->mode; + return RRErrorBase + BadRRMode; + } + if (!mode->userScreen) + return BadMatch; + if (mode->refcnt > 1) + return BadAccess; + FreeResource (stuff->mode, 0); + return Success; +} + +int +ProcRRAddOutputMode (ClientPtr client) +{ + REQUEST(xRRAddOutputModeReq); + RRModePtr mode; + 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; + } + + return RROutputAddUserMode (output, mode); +} + +int +ProcRRDeleteOutputMode (ClientPtr client) +{ + REQUEST(xRRDeleteOutputModeReq); + RRModePtr mode; + 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; + } + + return RROutputDeleteUserMode (output, mode); +} diff --git a/programs/Xserver/randr/rrmode.c.X.original b/programs/Xserver/randr/rrmode.c.X.original new file mode 100644 index 0000000..d507208 --- /dev/null +++ b/programs/Xserver/randr/rrmode.c.X.original @@ -0,0 +1,398 @@ +/* + * 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 "registry.h" + +RESTYPE RRModeType; + +static Bool +RRModeEqual (xRRModeInfo *a, xRRModeInfo *b) +{ + if (a->width != b->width) return FALSE; + if (a->height != b->height) return FALSE; + if (a->dotClock != b->dotClock) return FALSE; + if (a->hSyncStart != b->hSyncStart) return FALSE; + if (a->hSyncEnd != b->hSyncEnd) return FALSE; + if (a->hTotal != b->hTotal) return FALSE; + if (a->hSkew != b->hSkew) return FALSE; + if (a->vSyncStart != b->vSyncStart) return FALSE; + if (a->vSyncEnd != b->vSyncEnd) return FALSE; + if (a->vTotal != b->vTotal) return FALSE; + if (a->nameLength != b->nameLength) return FALSE; + if (a->modeFlags != b->modeFlags) return FALSE; + return TRUE; +} + +/* + * Keep a list so it's easy to find modes in the resource database. + */ +static int num_modes; +static RRModePtr *modes; + +static RRModePtr +RRModeCreate (xRRModeInfo *modeInfo, + const char *name, + ScreenPtr userScreen) +{ + RRModePtr mode, *newModes; + + if (!RRInit ()) + return NULL; + + mode = xalloc (sizeof (RRModeRec) + modeInfo->nameLength + 1); + if (!mode) + return NULL; + mode->refcnt = 1; + mode->mode = *modeInfo; + mode->name = (char *) (mode + 1); + memcpy (mode->name, name, modeInfo->nameLength); + mode->name[modeInfo->nameLength] = '\0'; + mode->userScreen = userScreen; + + if (num_modes) + newModes = xrealloc (modes, (num_modes + 1) * sizeof (RRModePtr)); + else + newModes = xalloc (sizeof (RRModePtr)); + + if (!newModes) + { + xfree (mode); + return NULL; + } + + mode->mode.id = FakeClientID(0); + if (!AddResource (mode->mode.id, RRModeType, (pointer) mode)) + return NULL; + modes = newModes; + modes[num_modes++] = mode; + + /* + * give the caller a reference to this mode + */ + ++mode->refcnt; + return mode; +} + +static RRModePtr +RRModeFindByName (const char *name, + CARD16 nameLength) +{ + int i; + RRModePtr mode; + + for (i = 0; i < num_modes; i++) + { + mode = modes[i]; + if (mode->mode.nameLength == nameLength && + !memcmp (name, mode->name, nameLength)) + { + return mode; + } + } + return NULL; +} + +RRModePtr +RRModeGet (xRRModeInfo *modeInfo, + const char *name) +{ + int i; + + for (i = 0; i < num_modes; i++) + { + RRModePtr mode = modes[i]; + if (RRModeEqual (&mode->mode, modeInfo) && + !memcmp (name, mode->name, modeInfo->nameLength)) + { + ++mode->refcnt; + return mode; + } + } + + return RRModeCreate (modeInfo, name, NULL); +} + +static RRModePtr +RRModeCreateUser (ScreenPtr pScreen, + xRRModeInfo *modeInfo, + const char *name, + int *error) +{ + RRModePtr mode; + + mode = RRModeFindByName (name, modeInfo->nameLength); + if (mode) + { + *error = BadName; + return NULL; + } + + mode = RRModeCreate (modeInfo, name, pScreen); + if (!mode) + { + *error = BadAlloc; + return NULL; + } + *error = Success; + return mode; +} + +RRModePtr * +RRModesForScreen (ScreenPtr pScreen, int *num_ret) +{ + rrScrPriv(pScreen); + int o, c, m; + RRModePtr *screen_modes; + int num_screen_modes = 0; + + screen_modes = xalloc ((num_modes ? num_modes : 1) * sizeof (RRModePtr)); + if (!screen_modes) + return NULL; + + /* + * Add modes from all outputs + */ + for (o = 0; o < pScrPriv->numOutputs; o++) + { + RROutputPtr output = pScrPriv->outputs[o]; + int m, n; + + for (m = 0; m < output->numModes + output->numUserModes; m++) + { + RRModePtr mode = (m < output->numModes ? + output->modes[m] : + output->userModes[m-output->numModes]); + for (n = 0; n < num_screen_modes; n++) + if (screen_modes[n] == mode) + break; + if (n == num_screen_modes) + screen_modes[num_screen_modes++] = mode; + } + } + /* + * Add modes from all crtcs. The goal is to + * make sure all available and active modes + * are visible to the client + */ + for (c = 0; c < pScrPriv->numCrtcs; c++) + { + RRCrtcPtr crtc = pScrPriv->crtcs[c]; + RRModePtr mode = crtc->mode; + int n; + + if (!mode) continue; + for (n = 0; n < num_screen_modes; n++) + if (screen_modes[n] == mode) + break; + if (n == num_screen_modes) + screen_modes[num_screen_modes++] = mode; + } + /* + * Add all user modes for this screen + */ + for (m = 0; m < num_modes; m++) + { + RRModePtr mode = modes[m]; + int n; + + if (mode->userScreen != pScreen) + continue; + for (n = 0; n < num_screen_modes; n++) + if (screen_modes[n] == mode) + break; + if (n == num_screen_modes) + screen_modes[num_screen_modes++] = mode; + } + + *num_ret = num_screen_modes; + return screen_modes; +} + +void +RRModeDestroy (RRModePtr mode) +{ + int m; + + if (--mode->refcnt > 0) + return; + for (m = 0; m < num_modes; m++) + { + if (modes[m] == mode) + { + memmove (modes + m, modes + m + 1, + (num_modes - m - 1) * sizeof (RRModePtr)); + num_modes--; + if (!num_modes) + { + xfree (modes); + modes = NULL; + } + break; + } + } + + xfree (mode); +} + +static int +RRModeDestroyResource (pointer value, XID pid) +{ + RRModeDestroy ((RRModePtr) value); + return 1; +} + +Bool +RRModeInit (void) +{ + assert (num_modes == 0); + assert (modes == NULL); + RRModeType = CreateNewResourceType (RRModeDestroyResource); + if (!RRModeType) + return FALSE; + RegisterResourceName (RRModeType, "MODE"); + return TRUE; +} + +int +ProcRRCreateMode (ClientPtr client) +{ + REQUEST(xRRCreateModeReq); + xRRCreateModeReply rep; + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + xRRModeInfo *modeInfo; + long units_after; + char *name; + int error, rc; + RRModePtr mode; + + REQUEST_AT_LEAST_SIZE (xRRCreateModeReq); + rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); + if (rc != Success) + return rc; + + pScreen = pWin->drawable.pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + modeInfo = &stuff->modeInfo; + name = (char *) (stuff + 1); + units_after = (stuff->length - (sizeof (xRRCreateModeReq) >> 2)); + + /* check to make sure requested name fits within the data provided */ + if ((int) (modeInfo->nameLength + 3) >> 2 > 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; + if (client->swapped) + { + int n; + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.mode, n); + } + WriteToClient(client, sizeof(xRRCreateModeReply), (char *)&rep); + + return client->noClientException; +} + +int +ProcRRDestroyMode (ClientPtr client) +{ + REQUEST(xRRDestroyModeReq); + RRModePtr mode; + + REQUEST_SIZE_MATCH(xRRDestroyModeReq); + mode = LookupIDByType (stuff->mode, RRModeType); + if (!mode) + { + client->errorValue = stuff->mode; + return RRErrorBase + BadRRMode; + } + if (!mode->userScreen) + return BadMatch; + if (mode->refcnt > 1) + return BadAccess; + FreeResource (stuff->mode, 0); + return Success; +} + +int +ProcRRAddOutputMode (ClientPtr client) +{ + REQUEST(xRRAddOutputModeReq); + RRModePtr mode; + 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; + } + + return RROutputAddUserMode (output, mode); +} + +int +ProcRRDeleteOutputMode (ClientPtr client) +{ + REQUEST(xRRDeleteOutputModeReq); + RRModePtr mode; + 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; + } + + return RROutputDeleteUserMode (output, mode); +} diff --git a/programs/Xserver/randr/rroutput.c b/programs/Xserver/randr/rroutput.c new file mode 100644 index 0000000..1ecde31 --- /dev/null +++ b/programs/Xserver/randr/rroutput.c @@ -0,0 +1,535 @@ +/* + * 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 "registry.h" + +RESTYPE RROutputType; + +/* + * Notify the output of some change + */ +void +RROutputChanged (RROutputPtr output, Bool configChanged) +{ + ScreenPtr pScreen = output->pScreen; + + output->changed = TRUE; + if (pScreen) + { + rrScrPriv (pScreen); + pScrPriv->changed = TRUE; + if (configChanged) + pScrPriv->configChanged = TRUE; + } +} + +/* + * Create an output + */ + +RROutputPtr +RROutputCreate (ScreenPtr pScreen, + const char *name, + int nameLength, + void *devPrivate) +{ + RROutputPtr output; + RROutputPtr *outputs; + rrScrPrivPtr pScrPriv; + + if (!RRInit()) + return NULL; + + pScrPriv = rrGetScrPriv(pScreen); + + if (pScrPriv->numOutputs) + outputs = xrealloc (pScrPriv->outputs, + (pScrPriv->numOutputs + 1) * sizeof (RROutputPtr)); + else + outputs = xalloc (sizeof (RROutputPtr)); + if (!outputs) + return FALSE; + + pScrPriv->outputs = outputs; + + output = xalloc (sizeof (RROutputRec) + nameLength + 1); + if (!output) + return NULL; + output->id = FakeClientID (0); + output->pScreen = pScreen; + output->name = (char *) (output + 1); + output->nameLength = nameLength; + memcpy (output->name, name, nameLength); + output->name[nameLength] = '\0'; + output->connection = RR_UnknownConnection; + output->subpixelOrder = SubPixelUnknown; + output->mmWidth = 0; + output->mmHeight = 0; + output->crtc = NULL; + output->numCrtcs = 0; + output->crtcs = NULL; + output->numClones = 0; + output->clones = NULL; + output->numModes = 0; + output->numPreferred = 0; + output->modes = NULL; + output->numUserModes = 0; + output->userModes = NULL; + output->properties = NULL; + output->pendingProperties = FALSE; + output->changed = FALSE; + output->devPrivate = devPrivate; + + if (!AddResource (output->id, RROutputType, (pointer) output)) + return NULL; + + pScrPriv->outputs[pScrPriv->numOutputs++] = output; + return output; +} + +/* + * Notify extension that output parameters have been changed + */ +Bool +RROutputSetClones (RROutputPtr output, + RROutputPtr *clones, + int numClones) +{ + RROutputPtr *newClones; + int i; + + if (numClones == output->numClones) + { + for (i = 0; i < numClones; i++) + if (output->clones[i] != clones[i]) + break; + if (i == numClones) + return TRUE; + } + if (numClones) + { + newClones = xalloc (numClones * sizeof (RROutputPtr)); + if (!newClones) + return FALSE; + } + else + newClones = NULL; + if (output->clones) + xfree (output->clones); + memcpy (newClones, clones, numClones * sizeof (RROutputPtr)); + output->clones = newClones; + output->numClones = numClones; + RROutputChanged (output, TRUE); + return TRUE; +} + +Bool +RROutputSetModes (RROutputPtr output, + RRModePtr *modes, + int numModes, + int numPreferred) +{ + RRModePtr *newModes; + int i; + + if (numModes == output->numModes && numPreferred == output->numPreferred) + { + for (i = 0; i < numModes; i++) + if (output->modes[i] != modes[i]) + break; + if (i == numModes) + { + for (i = 0; i < numModes; i++) + RRModeDestroy (modes[i]); + return TRUE; + } + } + + if (numModes) + { + newModes = xalloc (numModes * sizeof (RRModePtr)); + if (!newModes) + return FALSE; + } + else + newModes = NULL; + if (output->modes) + { + for (i = 0; i < output->numModes; i++) + RRModeDestroy (output->modes[i]); + xfree (output->modes); + } + memcpy (newModes, modes, numModes * sizeof (RRModePtr)); + output->modes = newModes; + output->numModes = numModes; + output->numPreferred = numPreferred; + RROutputChanged (output, TRUE); + return TRUE; +} + +int +RROutputAddUserMode (RROutputPtr output, + RRModePtr mode) +{ + int m; + ScreenPtr pScreen = output->pScreen; + rrScrPriv(pScreen); + RRModePtr *newModes; + + /* Check to see if this mode is already listed for this output */ + for (m = 0; m < output->numModes + output->numUserModes; m++) + { + RRModePtr e = (m < output->numModes ? + output->modes[m] : + output->userModes[m - output->numModes]); + if (mode == e) + return Success; + } + + /* Check with the DDX to see if this mode is OK */ + if (pScrPriv->rrOutputValidateMode) + if (!pScrPriv->rrOutputValidateMode (pScreen, output, mode)) + return BadMatch; + + if (output->userModes) + newModes = xrealloc (output->userModes, + (output->numUserModes + 1) * sizeof (RRModePtr)); + else + newModes = xalloc (sizeof (RRModePtr)); + if (!newModes) + return BadAlloc; + + output->userModes = newModes; + output->userModes[output->numUserModes++] = mode; + ++mode->refcnt; + RROutputChanged (output, TRUE); + RRTellChanged (pScreen); + return Success; +} + +int +RROutputDeleteUserMode (RROutputPtr output, + RRModePtr mode) +{ + int m; + + /* Find this mode in the user mode list */ + for (m = 0; m < output->numUserModes; m++) + { + RRModePtr e = output->userModes[m]; + + if (mode == e) + break; + } + /* Not there, access error */ + if (m == output->numUserModes) + return BadAccess; + + /* make sure the mode isn't active for this output */ + if (output->crtc && output->crtc->mode == mode) + return BadMatch; + + memmove (output->userModes + m, output->userModes + m + 1, + (output->numUserModes - m - 1) * sizeof (RRModePtr)); + output->numUserModes--; + RRModeDestroy (mode); + return Success; +} + +Bool +RROutputSetCrtcs (RROutputPtr output, + RRCrtcPtr *crtcs, + int numCrtcs) +{ + RRCrtcPtr *newCrtcs; + int i; + + if (numCrtcs == output->numCrtcs) + { + for (i = 0; i < numCrtcs; i++) + if (output->crtcs[i] != crtcs[i]) + break; + if (i == numCrtcs) + return TRUE; + } + if (numCrtcs) + { + newCrtcs = xalloc (numCrtcs * sizeof (RRCrtcPtr)); + if (!newCrtcs) + return FALSE; + } + else + newCrtcs = NULL; + if (output->crtcs) + xfree (output->crtcs); + memcpy (newCrtcs, crtcs, numCrtcs * sizeof (RRCrtcPtr)); + output->crtcs = newCrtcs; + output->numCrtcs = numCrtcs; + RROutputChanged (output, TRUE); + return TRUE; +} + +Bool +RROutputSetConnection (RROutputPtr output, + CARD8 connection) +{ + if (output->connection == connection) + return TRUE; + output->connection = connection; + RROutputChanged (output, TRUE); + return TRUE; +} + +Bool +RROutputSetSubpixelOrder (RROutputPtr output, + int subpixelOrder) +{ + if (output->subpixelOrder == subpixelOrder) + return TRUE; + + output->subpixelOrder = subpixelOrder; + RROutputChanged (output, FALSE); + return TRUE; +} + +Bool +RROutputSetPhysicalSize (RROutputPtr output, + int mmWidth, + int mmHeight) +{ + if (output->mmWidth == mmWidth && output->mmHeight == mmHeight) + return TRUE; + output->mmWidth = mmWidth; + output->mmHeight = mmHeight; + RROutputChanged (output, FALSE); + return TRUE; +} + + +void +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; + WriteEventsToClient (client, 1, (xEvent *) &oe); +} + +/* + * Destroy a Output at shutdown + */ +void +RROutputDestroy (RROutputPtr output) +{ + FreeResource (output->id, 0); +} + +static int +RROutputDestroyResource (pointer value, XID pid) +{ + RROutputPtr output = (RROutputPtr) value; + ScreenPtr pScreen = output->pScreen; + int m; + + if (pScreen) + { + rrScrPriv(pScreen); + int i; + + for (i = 0; i < pScrPriv->numOutputs; i++) + { + if (pScrPriv->outputs[i] == output) + { + memmove (pScrPriv->outputs + i, pScrPriv->outputs + i + 1, + (pScrPriv->numOutputs - (i + 1)) * sizeof (RROutputPtr)); + --pScrPriv->numOutputs; + break; + } + } + } + if (output->modes) + { + for (m = 0; m < output->numModes; m++) + RRModeDestroy (output->modes[m]); + xfree (output->modes); + } + + for (m = 0; m < output->numUserModes; m++) + RRModeDestroy (output->userModes[m]); + if (output->userModes) + xfree (output->userModes); + + if (output->crtcs) + xfree (output->crtcs); + if (output->clones) + xfree (output->clones); + RRDeleteAllOutputProperties (output); + xfree (output); + return 1; +} + +/* + * Initialize output type + */ +Bool +RROutputInit (void) +{ + RROutputType = CreateNewResourceType (RROutputDestroyResource); + if (!RROutputType) + return FALSE; + RegisterResourceName (RROutputType, "OUTPUT"); + return TRUE; +} + +#define OutputInfoExtra (SIZEOF(xRRGetOutputInfoReply) - 32) + +int +ProcRRGetOutputInfo (ClientPtr client) +{ + REQUEST(xRRGetOutputInfoReq); + xRRGetOutputInfoReply rep; + RROutputPtr output; + CARD8 *extra; + unsigned long extraLen; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + RRCrtc *crtcs; + RRMode *modes; + RROutput *clones; + char *name; + int i, n; + + REQUEST_SIZE_MATCH(xRRGetOutputInfoReq); + output = LookupOutput(client, stuff->output, DixReadAccess); + + if (!output) + { + client->errorValue = stuff->output; + return RRErrorBase + BadRROutput; + } + + pScreen = output->pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + rep.type = X_Reply; + 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; + + extraLen = ((output->numCrtcs + + output->numModes + output->numUserModes + + output->numClones + + ((rep.nameLength + 3) >> 2)) << 2); + + if (extraLen) + { + rep.length += extraLen >> 2; + extra = xalloc (extraLen); + if (!extra) + return BadAlloc; + } + else + extra = NULL; + + crtcs = (RRCrtc *) extra; + modes = (RRMode *) (crtcs + output->numCrtcs); + clones = (RROutput *) (modes + output->numModes + output->numUserModes); + name = (char *) (clones + output->numClones); + + for (i = 0; i < output->numCrtcs; i++) + { + crtcs[i] = output->crtcs[i]->id; + if (client->swapped) + swapl (&crtcs[i], n); + } + for (i = 0; i < output->numModes + output->numUserModes; i++) + { + if (i < output->numModes) + modes[i] = output->modes[i]->mode.id; + else + modes[i] = output->userModes[i - output->numModes]->mode.id; + if (client->swapped) + swapl (&modes[i], n); + } + for (i = 0; i < output->numClones; i++) + { + clones[i] = output->clones[i]->id; + if (client->swapped) + swapl (&clones[i], n); + } + memcpy (name, output->name, output->nameLength); + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.timestamp, n); + swapl(&rep.crtc, n); + swapl(&rep.mmWidth, n); + swapl(&rep.mmHeight, n); + swaps(&rep.nCrtcs, n); + swaps(&rep.nModes, n); + swaps(&rep.nClones, n); + swaps(&rep.nameLength, n); + } + WriteToClient(client, sizeof(xRRGetOutputInfoReply), (char *)&rep); + if (extraLen) + { + WriteToClient (client, extraLen, (char *) extra); + xfree (extra); + } + + return client->noClientException; +} diff --git a/programs/Xserver/randr/rrpointer.c b/programs/Xserver/randr/rrpointer.c new file mode 100644 index 0000000..c88a0f8 --- /dev/null +++ b/programs/Xserver/randr/rrpointer.c @@ -0,0 +1,145 @@ +/* + * 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" + +/* + * When the pointer moves, check to see if the specified position is outside + * any of theavailable CRTCs and move it to a 'sensible' place if so, where + * sensible is the closest monitor to the departing edge. + * + * Returns whether the position was adjusted + */ + +static Bool +RRCrtcContainsPosition (RRCrtcPtr crtc, int x, int y) +{ + RRModePtr mode = crtc->mode; + int scan_width, scan_height; + + if (!mode) + return FALSE; + + RRCrtcGetScanoutSize (crtc, &scan_width, &scan_height); + + if (crtc->x <= x && x < crtc->x + scan_width && + crtc->y <= y && y < crtc->y + scan_height) + return TRUE; + return FALSE; +} + +/* + * Find the CRTC nearest the specified position, ignoring 'skip' + */ +static void +RRPointerToNearestCrtc (ScreenPtr pScreen, int x, int y, RRCrtcPtr skip) +{ + rrScrPriv (pScreen); + int c; + RRCrtcPtr nearest = NULL; + int best = 0; + int best_dx = 0, best_dy = 0; + + for (c = 0; c < pScrPriv->numCrtcs; c++) + { + RRCrtcPtr crtc = pScrPriv->crtcs[c]; + RRModePtr mode = crtc->mode; + int dx, dy; + int dist; + int scan_width, scan_height; + + if (!mode) + continue; + if (crtc == skip) + continue; + + RRCrtcGetScanoutSize (crtc, &scan_width, &scan_height); + + if (x < crtc->x) + dx = crtc->x - x; + else if (x > crtc->x + scan_width) + dx = x - (crtc->x + scan_width); + else + dx = 0; + if (y < crtc->y) + dy = crtc->y - x; + else if (y > crtc->y + scan_height) + dy = y - (crtc->y + scan_height); + else + dy = 0; + dist = dx + dy; + if (!nearest || dist < best) + { + nearest = crtc; + best_dx = dx; + best_dy = dy; + } + } + if (best_dx || best_dy) + (*pScreen->SetCursorPosition) (pScreen, x + best_dx, y + best_dy, TRUE); + pScrPriv->pointerCrtc = nearest; +} + +void +RRPointerMoved (ScreenPtr pScreen, int x, int y) +{ + rrScrPriv (pScreen); + RRCrtcPtr pointerCrtc = pScrPriv->pointerCrtc; + int c; + + /* Check last known CRTC */ + if (pointerCrtc && RRCrtcContainsPosition (pointerCrtc, x, y)) + return; + + /* Check all CRTCs */ + for (c = 0; c < pScrPriv->numCrtcs; c++) + { + RRCrtcPtr crtc = pScrPriv->crtcs[c]; + + if (RRCrtcContainsPosition (crtc, x, y)) + { + /* Remember containing CRTC */ + pScrPriv->pointerCrtc = crtc; + return; + } + } + + /* None contain pointer, find nearest */ + RRPointerToNearestCrtc (pScreen, x, y, pointerCrtc); +} + +/* + * When the screen is reconfigured, move the pointer to the nearest + * CRTC + */ +void +RRPointerScreenConfigured (ScreenPtr pScreen) +{ + WindowPtr pRoot = GetCurrentRootWindow (); + ScreenPtr pCurrentScreen = pRoot ? pRoot->drawable.pScreen : NULL; + int x, y; + + if (pScreen != pCurrentScreen) + return; + GetSpritePosition (&x, &y); + RRPointerToNearestCrtc (pScreen, x, y, NULL); +} diff --git a/programs/Xserver/randr/rrproperty.c b/programs/Xserver/randr/rrproperty.c new file mode 100644 index 0000000..429246c --- /dev/null +++ b/programs/Xserver/randr/rrproperty.c @@ -0,0 +1,736 @@ +/* + * 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 void +RRDeliverEvent (ScreenPtr pScreen, xEvent *event, CARD32 mask) +{ + +} + +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); + } +} + +static void +RRInitOutputPropertyValue (RRPropertyValuePtr property_value) +{ + property_value->type = None; + property_value->format = 0; + property_value->size = 0; + property_value->data = NULL; +} + +static RRPropertyPtr +RRCreateOutputProperty (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; + RRInitOutputPropertyValue (&prop->current); + RRInitOutputPropertyValue (&prop->pending); + 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; + + 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); + } +} + +int +RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type, + int format, int mode, unsigned long len, + pointer 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; + Bool add = FALSE; + + size_in_bytes = format >> 3; + + /* first see if property already exists */ + prop = RRQueryOutputProperty (output, property); + if (!prop) /* just add to list */ + { + prop = RRCreateOutputProperty (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) + { + pointer new_data = NULL, old_data = NULL; + + total_size = total_len * size_in_bytes; + new_value.data = (pointer)xalloc (total_size); + if (!new_value.data && total_size) + { + if (add) + RRDestroyOutputProperty (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 = (pointer) (((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 = (pointer) (((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->rrOutputSetProperty && + !pScrPriv->rrOutputSetProperty(output->pScreen, output, + prop->propertyName, &new_value)) + { + if (new_value.data) + xfree (new_value.data); + return (BadValue); + } + if (prop_value->data) + xfree (prop_value->data); + *prop_value = new_value; + } + + else if (len == 0) + { + /* do nothing */ + } + + if (add) + { + prop->next = output->properties; + output->properties = prop; + } + + if (pending && prop->is_pending) + 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); +} + +Bool +RRPostPendingProperties (RROutputPtr output) +{ + RRPropertyValuePtr pending_value; + RRPropertyValuePtr current_value; + RRPropertyPtr property; + Bool ret = TRUE; + + if (!output->pendingProperties) + return TRUE; + + output->pendingProperties = FALSE; + for (property = output->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)) + continue; + + if (RRChangeOutputProperty (output, property->propertyName, + pending_value->type, pending_value->format, + PropModeReplace, pending_value->size, + pending_value->data, TRUE, + FALSE) != Success) + ret = FALSE; + } + return ret; +} + +RRPropertyPtr +RRQueryOutputProperty (RROutputPtr output, Atom property) +{ + RRPropertyPtr prop; + + for (prop = output->properties; prop; prop = prop->next) + if (prop->propertyName == property) + return prop; + return NULL; +} + +RRPropertyValuePtr +RRGetOutputProperty (RROutputPtr output, Atom property, Bool pending) +{ + RRPropertyPtr prop = RRQueryOutputProperty (output, property); + + if (!prop) + return NULL; + if (pending && prop->is_pending) + return &prop->pending; + else + return &prop->current; +} + +int +RRConfigureOutputProperty (RROutputPtr output, Atom property, + Bool pending, Bool range, Bool immutable, + int num_values, INT32 *values) +{ + RRPropertyPtr prop = RRQueryOutputProperty (output, property); + Bool add = FALSE; + INT32 *new_values; + + if (!prop) + { + prop = RRCreateOutputProperty (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)) + return BadMatch; + + new_values = xalloc (num_values * sizeof (INT32)); + if (!new_values && num_values) + 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) + { + if (prop->pending.data) + xfree (prop->pending.data); + RRInitOutputPropertyValue (&prop->pending); + } + + prop->is_pending = pending; + prop->range = range; + prop->immutable = immutable; + prop->num_valid = num_values; + if (prop->valid_values) + xfree (prop->valid_values); + prop->valid_values = new_values; + + if (add) { + prop->next = output->properties; + output->properties = prop; + } + + return Success; +} + +int +ProcRRListOutputProperties (ClientPtr client) +{ + REQUEST(xRRListOutputPropertiesReq); + Atom *pAtoms = NULL, *temppAtoms; + xRRListOutputPropertiesReply rep; + int numProps = 0; + RROutputPtr output; + RRPropertyPtr prop; + + REQUEST_SIZE_MATCH(xRRListOutputPropertiesReq); + + output = LookupOutput (client, stuff->output, DixReadAccess); + + if (!output) + return RRErrorBase + BadRROutput; + + for (prop = output->properties; prop; prop = prop->next) + numProps++; + if (numProps) + if(!(pAtoms = (Atom *)xalloc(numProps * sizeof(Atom)))) + return(BadAlloc); + + rep.type = X_Reply; + rep.length = (numProps * sizeof(Atom)) >> 2; + rep.sequenceNumber = client->sequence; + rep.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) + { + client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write; + WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms); + xfree(pAtoms); + } + return(client->noClientException); +} + +int +ProcRRQueryOutputProperty (ClientPtr client) +{ + REQUEST(xRRQueryOutputPropertyReq); + xRRQueryOutputPropertyReply rep; + RROutputPtr output; + RRPropertyPtr prop; + char *extra; + + REQUEST_SIZE_MATCH(xRRQueryOutputPropertyReq); + + output = LookupOutput (client, stuff->output, DixReadAccess); + + if (!output) + return RRErrorBase + BadRROutput; + + prop = RRQueryOutputProperty (output, stuff->property); + if (!prop) + return BadName; + + if (prop->num_valid) { + extra = xalloc(prop->num_valid * sizeof(INT32)); + 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; + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + } + WriteToClient (client, sizeof (xRRQueryOutputPropertyReply), (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(client->noClientException); +} + +int +ProcRRConfigureOutputProperty (ClientPtr client) +{ + REQUEST(xRRConfigureOutputPropertyReq); + RROutputPtr output; + int num_valid; + + REQUEST_AT_LEAST_SIZE(xRRConfigureOutputPropertyReq); + + output = LookupOutput (client, stuff->output, DixReadAccess); + + if (!output) + return RRErrorBase + BadRROutput; + + num_valid = stuff->length - (sizeof (xRRConfigureOutputPropertyReq) >> 2); + return RRConfigureOutputProperty (output, stuff->property, + stuff->pending, stuff->range, + FALSE, num_valid, + (INT32 *) (stuff + 1)); +} + +int +ProcRRChangeOutputProperty (ClientPtr client) +{ + REQUEST(xRRChangeOutputPropertyReq); + RROutputPtr output; + char format, mode; + unsigned long len; + int sizeInBytes; + int totalSize; + int err; + + REQUEST_AT_LEAST_SIZE(xRRChangeOutputPropertyReq); + 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 > ((0xffffffff - sizeof(xChangePropertyReq)) >> 2)) + return BadLength; + sizeInBytes = format>>3; + totalSize = len * sizeInBytes; + REQUEST_FIXED_SIZE(xRRChangeOutputPropertyReq, totalSize); + + output = LookupOutput (client, stuff->output, DixWriteAccess); + if (!output) + return RRErrorBase + BadRROutput; + + if (!ValidAtom(stuff->property)) + { + client->errorValue = stuff->property; + return(BadAtom); + } + if (!ValidAtom(stuff->type)) + { + client->errorValue = stuff->type; + return(BadAtom); + } + + err = RRChangeOutputProperty(output, stuff->property, + stuff->type, (int)format, + (int)mode, len, (pointer)&stuff[1], TRUE, TRUE); + if (err != Success) + return err; + else + return client->noClientException; +} + +int +ProcRRDeleteOutputProperty (ClientPtr client) +{ + REQUEST(xRRDeleteOutputPropertyReq); + RROutputPtr output; + + REQUEST_SIZE_MATCH(xRRDeleteOutputPropertyReq); + UpdateCurrentTime(); + output = LookupOutput (client, stuff->output, DixWriteAccess); + if (!output) + return RRErrorBase + BadRROutput; + + if (!ValidAtom(stuff->property)) + { + client->errorValue = stuff->property; + return (BadAtom); + } + + + RRDeleteOutputProperty(output, stuff->property); + return client->noClientException; +} + +int +ProcRRGetOutputProperty (ClientPtr client) +{ + REQUEST(xRRGetOutputPropertyReq); + RRPropertyPtr prop, *prev; + RRPropertyValuePtr prop_value; + unsigned long n, len, ind; + RROutputPtr output; + xRRGetOutputPropertyReply reply; + char *extra; + + REQUEST_SIZE_MATCH(xRRGetOutputPropertyReq); + if (stuff->delete) + UpdateCurrentTime(); + output = LookupOutput (client, stuff->output, + stuff->delete ? DixWriteAccess : + DixReadAccess); + if (!output) + return RRErrorBase + BadRROutput; + + 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 = &output->properties; (prop = *prev); prev = &prop->next) + if (prop->propertyName == stuff->property) + break; + + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + if (!prop) + { + reply.nItems = 0; + reply.length = 0; + reply.bytesAfter = 0; + 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); + } + WriteToClient(client, sizeof(xRRGetOutputPropertyReply), &reply); + return(client->noClientException); + } + + if (prop->immutable && stuff->delete) + return BadAccess; + + if (stuff->pending && prop->is_pending) + prop_value = &prop->pending; + else + prop_value = &prop->current; + + /* 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) { + 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); + } + +/* + * 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 = (len + 3) >> 2; + 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)) + { + 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); + } + + 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); + 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; + RRDestroyOutputProperty (prop); + } + return(client->noClientException); +} + diff --git a/programs/Xserver/randr/rrscreen.c b/programs/Xserver/randr/rrscreen.c new file mode 100644 index 0000000..9b3935e --- /dev/null +++ b/programs/Xserver/randr/rrscreen.c @@ -0,0 +1,1030 @@ +/* + * 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. + */ + +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */ +/* */ +/* NX-X11, NX protocol compression and NX extensions to this software */ +/* are copyright of NoMachine. Redistribution and use of the present */ +/* software is allowed according to terms specified in the file LICENSE */ +/* which comes in the source distribution. */ +/* */ +/* Check http://www.nomachine.com/licensing.html for applicability. */ +/* */ +/* NX and NoMachine are trademarks of Medialogic S.p.A. */ +/* */ +/* All rights reserved. */ +/* */ +/**************************************************************************/ + +#include "randrstr.h" + +extern char *ConnectionInfo; + +static int padlength[4] = {0, 3, 2, 1}; + +static CARD16 +RR10CurrentSizeID (ScreenPtr pScreen); + +/* + * Edit connection information block so that new clients + * see the current screen size on connect + */ +static void +RREditConnectionInfo (ScreenPtr pScreen) +{ + xConnSetup *connSetup; + char *vendor; + xPixmapFormat *formats; + xWindowRoot *root; + xDepth *depth; + xVisualType *visual; + int screen = 0; + int d; + + connSetup = (xConnSetup *) ConnectionInfo; + vendor = (char *) connSetup + sizeof (xConnSetup); + formats = (xPixmapFormat *) ((char *) vendor + + connSetup->nbytesVendor + + padlength[connSetup->nbytesVendor & 3]); + root = (xWindowRoot *) ((char *) formats + + sizeof (xPixmapFormat) * screenInfo.numPixmapFormats); + while (screen != pScreen->myNum) + { + depth = (xDepth *) ((char *) root + + sizeof (xWindowRoot)); + for (d = 0; d < root->nDepths; d++) + { + visual = (xVisualType *) ((char *) depth + + sizeof (xDepth)); + depth = (xDepth *) ((char *) visual + + depth->nVisuals * sizeof (xVisualType)); + } + root = (xWindowRoot *) ((char *) depth); + screen++; + } + root->pixWidth = pScreen->width; + root->pixHeight = pScreen->height; + root->mmWidth = pScreen->mmWidth; + root->mmHeight = pScreen->mmHeight; +} + +void +RRSendConfigNotify (ScreenPtr pScreen) +{ + WindowPtr pWin = WindowTable[pScreen->myNum]; + xEvent event; + + 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); +} + +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; +#endif + + se.sequenceNumber = client->sequence; + se.sizeID = RR10CurrentSizeID (pScreen); + + if (se.rotation & (RR_Rotate_90 | RR_Rotate_270)) { + se.widthInPixels = pScreen->height; + se.heightInPixels = pScreen->width; + se.widthInMillimeters = pScreen->mmHeight; + se.heightInMillimeters = pScreen->mmWidth; + } else { + se.widthInPixels = pScreen->width; + se.heightInPixels = pScreen->height; + se.widthInMillimeters = pScreen->mmWidth; + se.heightInMillimeters = pScreen->mmHeight; + } + + WriteEventsToClient (client, 1, (xEvent *) &se); +} + +/* + * Notify the extension that the screen size has been changed. + * The driver is responsible for calling this whenever it has changed + * the size of the screen + */ +void +RRScreenSizeNotify (ScreenPtr pScreen) +{ + rrScrPriv(pScreen); + /* + * Deliver ConfigureNotify events when root changes + * pixel size + */ + if (pScrPriv->width == pScreen->width && + pScrPriv->height == pScreen->height && + pScrPriv->mmWidth == pScreen->mmWidth && + pScrPriv->mmHeight == pScreen->mmHeight) + return; + + pScrPriv->width = pScreen->width; + pScrPriv->height = pScreen->height; + pScrPriv->mmWidth = pScreen->mmWidth; + pScrPriv->mmHeight = pScreen->mmHeight; + pScrPriv->changed = TRUE; +/* pScrPriv->sizeChanged = TRUE; */ + + RRTellChanged (pScreen); + RRSendConfigNotify (pScreen); + RREditConnectionInfo (pScreen); + + RRPointerScreenConfigured (pScreen); + /* + * Fix pointer bounds and location + */ + ScreenRestructured (pScreen); +} + +/* + * Request that the screen be resized + */ +Bool +RRScreenSizeSet (ScreenPtr pScreen, + CARD16 width, + CARD16 height, + CARD32 mmWidth, + CARD32 mmHeight) +{ + rrScrPriv(pScreen); + +#if RANDR_12_INTERFACE + if (pScrPriv->rrScreenSetSize) + { + return (*pScrPriv->rrScreenSetSize) (pScreen, + width, height, + mmWidth, mmHeight); + } +#endif +#if RANDR_10_INTERFACE + if (pScrPriv->rrSetConfig) + { + return TRUE; /* can't set size separately */ + } +#endif + return FALSE; +} + +/* + * Retrieve valid screen size range + */ +int +ProcRRGetScreenSizeRange (ClientPtr client) +{ + REQUEST(xRRGetScreenSizeRangeReq); + xRRGetScreenSizeRangeReply rep; + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + int rc; + + REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); + #ifndef NXAGENT_SERVER + rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); + #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; + + if (pScrPriv) + { + if (!RRGetInfo (pScreen)) + return BadAlloc; + rep.minWidth = pScrPriv->minWidth; + rep.minHeight = pScrPriv->minHeight; + rep.maxWidth = pScrPriv->maxWidth; + rep.maxHeight = pScrPriv->maxHeight; + } + else + { + rep.maxWidth = rep.minWidth = pScreen->width; + rep.maxHeight = rep.minHeight = pScreen->height; + } + if (client->swapped) + { + int n; + + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.minWidth, n); + swaps(&rep.minHeight, n); + swaps(&rep.maxWidth, n); + swaps(&rep.maxHeight, n); + } + WriteToClient(client, sizeof(xRRGetScreenSizeRangeReply), (char *)&rep); + return (client->noClientException); +} + +int +ProcRRSetScreenSize (ClientPtr client) +{ + REQUEST(xRRSetScreenSizeReq); + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + int i, rc; + + REQUEST_SIZE_MATCH(xRRSetScreenSizeReq); + #ifndef NXAGENT_SERVER + rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); + #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 (stuff->width < pScrPriv->minWidth || pScrPriv->maxWidth < stuff->width) + { + client->errorValue = stuff->width; + return BadValue; + } + if (stuff->height < pScrPriv->minHeight || + pScrPriv->maxHeight < stuff->height) + { + client->errorValue = stuff->height; + return BadValue; + } + for (i = 0; i < pScrPriv->numCrtcs; i++) + { + RRCrtcPtr crtc = pScrPriv->crtcs[i]; + RRModePtr mode = crtc->mode; + if (mode) + { + int source_width = mode->mode.width; + int source_height = mode->mode.height; + Rotation rotation = crtc->rotation; + + if (rotation == RR_Rotate_90 || rotation == RR_Rotate_270) + { + source_width = mode->mode.height; + source_height = mode->mode.width; + } + + if (crtc->x + source_width > stuff->width || + crtc->y + source_height > stuff->height) + return BadMatch; + } + } + if (stuff->widthInMillimeters == 0 || stuff->heightInMillimeters == 0) + { + client->errorValue = 0; + return BadValue; + } + if (!RRScreenSizeSet (pScreen, + stuff->width, stuff->height, + stuff->widthInMillimeters, + stuff->heightInMillimeters)) + { + return BadMatch; + } + return Success; +} + +int +ProcRRGetScreenResources (ClientPtr client) +{ + REQUEST(xRRGetScreenResourcesReq); + xRRGetScreenResourcesReply rep; + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + CARD8 *extra; + unsigned long extraLen; + int i, n, rc; + RRCrtc *crtcs; + RROutput *outputs; + xRRModeInfo *modeinfos; + CARD8 *names; + + REQUEST_SIZE_MATCH(xRRGetScreenResourcesReq); + #ifndef NXAGENT_SERVER + rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); + #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)) + return BadAlloc; + + 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; + extra = NULL; + extraLen = 0; + } + else + { + RRModePtr *modes; + int num_modes; + + modes = RRModesForScreen (pScreen, &num_modes); + 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; + + 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)); + + extraLen = rep.length << 2; + if (extraLen) + { + extra = xalloc (extraLen); + if (!extra) + { + xfree (modes); + return BadAlloc; + } + } + else + extra = NULL; + + crtcs = (RRCrtc *) extra; + outputs = (RROutput *) (crtcs + pScrPriv->numCrtcs); + modeinfos = (xRRModeInfo *) (outputs + pScrPriv->numOutputs); + names = (CARD8 *) (modeinfos + num_modes); + + 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); + } + + for (i = 0; i < num_modes; i++) + { + RRModePtr mode = modes[i]; + modeinfos[i] = mode->mode; + if (client->swapped) + { + 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); + } + memcpy (names, mode->name, + mode->mode.nameLength); + names += mode->mode.nameLength; + } + xfree (modes); + assert (((((char *) names - (char *) extra) + 3) >> 2) == 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 client->noClientException; +} + +typedef struct _RR10Data { + RRScreenSizePtr sizes; + int nsize; + int nrefresh; + int size; + CARD16 refresh; +} RR10DataRec, *RR10DataPtr; + +/* + * Convert 1.2 monitor data into 1.0 screen data + */ +static RR10DataPtr +RR10GetData (ScreenPtr pScreen, RROutputPtr output) +{ + RR10DataPtr data; + RRScreenSizePtr size; + int nmode = output->numModes + output->numUserModes; + int o, os, l, r; + RRScreenRatePtr refresh; + CARD16 vRefresh; + RRModePtr mode; + Bool *used; + + /* Make sure there is plenty of space for any combination */ + data = malloc (sizeof (RR10DataRec) + + sizeof (RRScreenSize) * nmode + + sizeof (RRScreenRate) * nmode + + sizeof (Bool) * nmode); + if (!data) + return NULL; + size = (RRScreenSizePtr) (data + 1); + refresh = (RRScreenRatePtr) (size + nmode); + used = (Bool *) (refresh + nmode); + memset (used, '\0', sizeof (Bool) * nmode); + data->sizes = size; + data->nsize = 0; + data->nrefresh = 0; + data->size = 0; + data->refresh = 0; + + /* + * find modes not yet listed + */ + for (o = 0; o < output->numModes + output->numUserModes; o++) + { + if (used[o]) continue; + + if (o < output->numModes) + mode = output->modes[o]; + else + mode = output->userModes[o - output->numModes]; + + l = data->nsize; + size[l].id = data->nsize; + size[l].width = mode->mode.width; + size[l].height = mode->mode.height; + if (output->mmWidth && output->mmHeight) { + size[l].mmWidth = output->mmWidth; + size[l].mmHeight = output->mmHeight; + } else { + size[l].mmWidth = pScreen->mmWidth; + size[l].mmHeight = pScreen->mmHeight; + } + size[l].nRates = 0; + size[l].pRates = &refresh[data->nrefresh]; + data->nsize++; + + /* + * Find all modes with matching size + */ + for (os = o; os < output->numModes + output->numUserModes; os++) + { + if (os < output->numModes) + mode = output->modes[os]; + else + mode = output->userModes[os - output->numModes]; + if (mode->mode.width == size[l].width && + mode->mode.height == size[l].height) + { + vRefresh = RRVerticalRefresh (&mode->mode); + used[os] = TRUE; + + for (r = 0; r < size[l].nRates; r++) + if (vRefresh == size[l].pRates[r].rate) + break; + if (r == size[l].nRates) + { + size[l].pRates[r].rate = vRefresh; + size[l].pRates[r].mode = mode; + size[l].nRates++; + data->nrefresh++; + } + if (mode == output->crtc->mode) + { + data->size = l; + data->refresh = vRefresh; + } + } + } + } + return data; +} + +int +ProcRRGetScreenInfo (ClientPtr client) +{ + REQUEST(xRRGetScreenInfoReq); + xRRGetScreenInfoReply rep; + WindowPtr pWin; + int n, rc; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + CARD8 *extra; + unsigned long extraLen; + RROutputPtr output; + + REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); + #ifndef NXAGENT_SERVER + rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); + #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)) + 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; + extra = 0; + extraLen = 0; + } + else + { + int i, j; + xScreenSizes *size; + CARD16 *rates; + CARD8 *data8; + Bool has_rate = RRClientKnowsRates (client); + RR10DataPtr pData; + RRScreenSizePtr pSize; + + pData = RR10GetData (pScreen, output); + 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; + + extraLen = (rep.nSizes * sizeof (xScreenSizes) + + rep.nrateEnts * sizeof (CARD16)); + + if (extraLen) + { + extra = (CARD8 *) xalloc (extraLen); + if (!extra) + { + xfree (pData); + return BadAlloc; + } + } + else + extra = NULL; + + /* + * First comes the size information + */ + size = (xScreenSizes *) extra; + rates = (CARD16 *) (size + rep.nSizes); + for (i = 0; i < pData->nsize; i++) + { + pSize = &pData->sizes[i]; + size->widthInPixels = pSize->width; + size->heightInPixels = pSize->height; + size->widthInMillimeters = pSize->mmWidth; + size->heightInMillimeters = pSize->mmHeight; + if (client->swapped) + { + swaps (&size->widthInPixels, n); + swaps (&size->heightInPixels, n); + swaps (&size->widthInMillimeters, n); + swaps (&size->heightInMillimeters, n); + } + size++; + if (has_rate) + { + *rates = pSize->nRates; + if (client->swapped) + { + swaps (rates, n); + } + rates++; + for (j = 0; j < pSize->nRates; j++) + { + *rates = pSize->pRates[j].rate; + if (client->swapped) + { + swaps (rates, n); + } + rates++; + } + } + } + xfree (pData); + + data8 = (CARD8 *) rates; + + if (data8 - (CARD8 *) extra != extraLen) + FatalError ("RRGetScreenInfo bad extra len %ld != %ld\n", + (unsigned long)(data8 - (CARD8 *) extra), extraLen); + rep.length = (extraLen + 3) >> 2; + } + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.timestamp, n); + swaps(&rep.rotation, n); + swaps(&rep.nSizes, n); + swaps(&rep.sizeID, n); + swaps(&rep.rate, n); + swaps(&rep.nrateEnts, n); + } + WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *)&rep); + if (extraLen) + { + WriteToClient (client, extraLen, (char *) extra); + xfree (extra); + } + return (client->noClientException); +} + +int +ProcRRSetScreenConfig (ClientPtr client) +{ + REQUEST(xRRSetScreenConfigReq); + xRRSetScreenConfigReply rep; + DrawablePtr pDraw; + int n, rc; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + TimeStamp time; + int i; + Rotation rotation; + int rate; + Bool has_rate; + RROutputPtr output; + RRCrtcPtr crtc; + RRModePtr mode; + RR10DataPtr pData = NULL; + RRScreenSizePtr pSize; + int width, height; + + UpdateCurrentTime (); + + if (RRClientKnowsRates (client)) + { + REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); + has_rate = TRUE; + } + else + { + REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); + has_rate = FALSE; + } + + #ifndef NXAGENT_SERVER + rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess); + #else + pDraw = SecurityLookupDrawable(stuff->drawable, client, SecurityWriteAccess); + rc = pDraw ? Success : BadDrawable; + #endif + if (rc != Success) + return rc; + + pScreen = pDraw->pScreen; + + pScrPriv = rrGetScrPriv(pScreen); + + time = ClientTimeToServerTime(stuff->timestamp); + + if (!pScrPriv) + { + time = currentTime; + rep.status = RRSetConfigFailed; + goto sendReply; + } + if (!RRGetInfo (pScreen)) + return BadAlloc; + + output = RRFirstOutput (pScreen); + if (!output) + { + time = currentTime; + rep.status = RRSetConfigFailed; + goto sendReply; + } + + crtc = output->crtc; + + /* + * If the client's config timestamp is not the same as the last config + * timestamp, then the config information isn't up-to-date and + * can't even be validated. + * + * Note that the client only knows about the milliseconds part of the + * timestamp, so using CompareTimeStamps here would cause randr to suddenly + * stop working after several hours have passed (freedesktop bug #6502). + */ + if (stuff->configTimestamp != pScrPriv->lastConfigTime.milliseconds) + { + rep.status = RRSetConfigInvalidConfigTime; + goto sendReply; + } + + pData = RR10GetData (pScreen, output); + if (!pData) + return BadAlloc; + + if (stuff->sizeID >= pData->nsize) + { + /* + * Invalid size ID + */ + client->errorValue = stuff->sizeID; + xfree (pData); + return BadValue; + } + pSize = &pData->sizes[stuff->sizeID]; + + /* + * Validate requested rotation + */ + rotation = (Rotation) stuff->rotation; + + /* test the rotation bits only! */ + switch (rotation & 0xf) { + case RR_Rotate_0: + case RR_Rotate_90: + case RR_Rotate_180: + case RR_Rotate_270: + break; + default: + /* + * Invalid rotation + */ + client->errorValue = stuff->rotation; + xfree (pData); + return BadValue; + } + + if ((~crtc->rotations) & rotation) + { + /* + * requested rotation or reflection not supported by screen + */ + client->errorValue = stuff->rotation; + xfree (pData); + return BadMatch; + } + + /* + * Validate requested refresh + */ + if (has_rate) + rate = (int) stuff->rate; + else + rate = 0; + + if (rate) + { + for (i = 0; i < pSize->nRates; i++) + { + if (pSize->pRates[i].rate == rate) + break; + } + if (i == pSize->nRates) + { + /* + * Invalid rate + */ + client->errorValue = rate; + xfree (pData); + return BadValue; + } + mode = pSize->pRates[i].mode; + } + else + mode = pSize->pRates[0].mode; + + /* + * 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 the screen size is changing, adjust all of the other outputs + * to fit the new size, mirroring as much as possible + */ + 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 != 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; + /* XXX recover from failure */ + goto sendReply; + } + } + if (!RRScreenSizeSet (pScreen, width, height, + pScreen->mmWidth, pScreen->mmHeight)) + { + rep.status = RRSetConfigFailed; + /* XXX recover from failure */ + goto sendReply; + } + } + + if (!RRCrtcSet (crtc, mode, 0, 0, stuff->rotation, 1, &output)) + rep.status = RRSetConfigFailed; + #ifndef NXAGENT_SERVER /* Bug 21987 */ + else + rep.status = RRSetConfigSuccess; + #else + else { + rep.status = RRSetConfigSuccess; + pScrPriv->lastSetTime = time; + } + #endif + + /* + * XXX Configure other crtcs to mirror as much as possible + */ + +sendReply: + + if (pData) + xfree (pData); + + rep.type = X_Reply; + /* rep.status has already been filled in */ + rep.length = 0; + rep.sequenceNumber = client->sequence; + + rep.newTimestamp = pScrPriv->lastSetTime.milliseconds; + rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds; + rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id; + + if (client->swapped) + { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.newTimestamp, n); + swapl(&rep.newConfigTimestamp, n); + swapl(&rep.root, n); + } + WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *)&rep); + + return (client->noClientException); +} + +static CARD16 +RR10CurrentSizeID (ScreenPtr pScreen) +{ + CARD16 sizeID = 0xffff; + RROutputPtr output = RRFirstOutput (pScreen); + + if (output) + { + RR10DataPtr data = RR10GetData (pScreen, output); + if (data) + { + int i; + for (i = 0; i < data->nsize; i++) + if (data->sizes[i].width == pScreen->width && + data->sizes[i].height == pScreen->height) + { + sizeID = (CARD16) i; + break; + } + xfree (data); + } + } + return sizeID; +} diff --git a/programs/Xserver/randr/rrscreen.c.NX.original b/programs/Xserver/randr/rrscreen.c.NX.original new file mode 100644 index 0000000..9b3935e --- /dev/null +++ b/programs/Xserver/randr/rrscreen.c.NX.original @@ -0,0 +1,1030 @@ +/* + * 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. + */ + +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */ +/* */ +/* NX-X11, NX protocol compression and NX extensions to this software */ +/* are copyright of NoMachine. Redistribution and use of the present */ +/* software is allowed according to terms specified in the file LICENSE */ +/* which comes in the source distribution. */ +/* */ +/* Check http://www.nomachine.com/licensing.html for applicability. */ +/* */ +/* NX and NoMachine are trademarks of Medialogic S.p.A. */ +/* */ +/* All rights reserved. */ +/* */ +/**************************************************************************/ + +#include "randrstr.h" + +extern char *ConnectionInfo; + +static int padlength[4] = {0, 3, 2, 1}; + +static CARD16 +RR10CurrentSizeID (ScreenPtr pScreen); + +/* + * Edit connection information block so that new clients + * see the current screen size on connect + */ +static void +RREditConnectionInfo (ScreenPtr pScreen) +{ + xConnSetup *connSetup; + char *vendor; + xPixmapFormat *formats; + xWindowRoot *root; + xDepth *depth; + xVisualType *visual; + int screen = 0; + int d; + + connSetup = (xConnSetup *) ConnectionInfo; + vendor = (char *) connSetup + sizeof (xConnSetup); + formats = (xPixmapFormat *) ((char *) vendor + + connSetup->nbytesVendor + + padlength[connSetup->nbytesVendor & 3]); + root = (xWindowRoot *) ((char *) formats + + sizeof (xPixmapFormat) * screenInfo.numPixmapFormats); + while (screen != pScreen->myNum) + { + depth = (xDepth *) ((char *) root + + sizeof (xWindowRoot)); + for (d = 0; d < root->nDepths; d++) + { + visual = (xVisualType *) ((char *) depth + + sizeof (xDepth)); + depth = (xDepth *) ((char *) visual + + depth->nVisuals * sizeof (xVisualType)); + } + root = (xWindowRoot *) ((char *) depth); + screen++; + } + root->pixWidth = pScreen->width; + root->pixHeight = pScreen->height; + root->mmWidth = pScreen->mmWidth; + root->mmHeight = pScreen->mmHeight; +} + +void +RRSendConfigNotify (ScreenPtr pScreen) +{ + WindowPtr pWin = WindowTable[pScreen->myNum]; + xEvent event; + + 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); +} + +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; +#endif + + se.sequenceNumber = client->sequence; + se.sizeID = RR10CurrentSizeID (pScreen); + + if (se.rotation & (RR_Rotate_90 | RR_Rotate_270)) { + se.widthInPixels = pScreen->height; + se.heightInPixels = pScreen->width; + se.widthInMillimeters = pScreen->mmHeight; + se.heightInMillimeters = pScreen->mmWidth; + } else { + se.widthInPixels = pScreen->width; + se.heightInPixels = pScreen->height; + se.widthInMillimeters = pScreen->mmWidth; + se.heightInMillimeters = pScreen->mmHeight; + } + + WriteEventsToClient (client, 1, (xEvent *) &se); +} + +/* + * Notify the extension that the screen size has been changed. + * The driver is responsible for calling this whenever it has changed + * the size of the screen + */ +void +RRScreenSizeNotify (ScreenPtr pScreen) +{ + rrScrPriv(pScreen); + /* + * Deliver ConfigureNotify events when root changes + * pixel size + */ + if (pScrPriv->width == pScreen->width && + pScrPriv->height == pScreen->height && + pScrPriv->mmWidth == pScreen->mmWidth && + pScrPriv->mmHeight == pScreen->mmHeight) + return; + + pScrPriv->width = pScreen->width; + pScrPriv->height = pScreen->height; + pScrPriv->mmWidth = pScreen->mmWidth; + pScrPriv->mmHeight = pScreen->mmHeight; + pScrPriv->changed = TRUE; +/* pScrPriv->sizeChanged = TRUE; */ + + RRTellChanged (pScreen); + RRSendConfigNotify (pScreen); + RREditConnectionInfo (pScreen); + + RRPointerScreenConfigured (pScreen); + /* + * Fix pointer bounds and location + */ + ScreenRestructured (pScreen); +} + +/* + * Request that the screen be resized + */ +Bool +RRScreenSizeSet (ScreenPtr pScreen, + CARD16 width, + CARD16 height, + CARD32 mmWidth, + CARD32 mmHeight) +{ + rrScrPriv(pScreen); + +#if RANDR_12_INTERFACE + if (pScrPriv->rrScreenSetSize) + { + return (*pScrPriv->rrScreenSetSize) (pScreen, + width, height, + mmWidth, mmHeight); + } +#endif +#if RANDR_10_INTERFACE + if (pScrPriv->rrSetConfig) + { + return TRUE; /* can't set size separately */ + } +#endif + return FALSE; +} + +/* + * Retrieve valid screen size range + */ +int +ProcRRGetScreenSizeRange (ClientPtr client) +{ + REQUEST(xRRGetScreenSizeRangeReq); + xRRGetScreenSizeRangeReply rep; + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + int rc; + + REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); + #ifndef NXAGENT_SERVER + rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); + #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; + + if (pScrPriv) + { + if (!RRGetInfo (pScreen)) + return BadAlloc; + rep.minWidth = pScrPriv->minWidth; + rep.minHeight = pScrPriv->minHeight; + rep.maxWidth = pScrPriv->maxWidth; + rep.maxHeight = pScrPriv->maxHeight; + } + else + { + rep.maxWidth = rep.minWidth = pScreen->width; + rep.maxHeight = rep.minHeight = pScreen->height; + } + if (client->swapped) + { + int n; + + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.minWidth, n); + swaps(&rep.minHeight, n); + swaps(&rep.maxWidth, n); + swaps(&rep.maxHeight, n); + } + WriteToClient(client, sizeof(xRRGetScreenSizeRangeReply), (char *)&rep); + return (client->noClientException); +} + +int +ProcRRSetScreenSize (ClientPtr client) +{ + REQUEST(xRRSetScreenSizeReq); + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + int i, rc; + + REQUEST_SIZE_MATCH(xRRSetScreenSizeReq); + #ifndef NXAGENT_SERVER + rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); + #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 (stuff->width < pScrPriv->minWidth || pScrPriv->maxWidth < stuff->width) + { + client->errorValue = stuff->width; + return BadValue; + } + if (stuff->height < pScrPriv->minHeight || + pScrPriv->maxHeight < stuff->height) + { + client->errorValue = stuff->height; + return BadValue; + } + for (i = 0; i < pScrPriv->numCrtcs; i++) + { + RRCrtcPtr crtc = pScrPriv->crtcs[i]; + RRModePtr mode = crtc->mode; + if (mode) + { + int source_width = mode->mode.width; + int source_height = mode->mode.height; + Rotation rotation = crtc->rotation; + + if (rotation == RR_Rotate_90 || rotation == RR_Rotate_270) + { + source_width = mode->mode.height; + source_height = mode->mode.width; + } + + if (crtc->x + source_width > stuff->width || + crtc->y + source_height > stuff->height) + return BadMatch; + } + } + if (stuff->widthInMillimeters == 0 || stuff->heightInMillimeters == 0) + { + client->errorValue = 0; + return BadValue; + } + if (!RRScreenSizeSet (pScreen, + stuff->width, stuff->height, + stuff->widthInMillimeters, + stuff->heightInMillimeters)) + { + return BadMatch; + } + return Success; +} + +int +ProcRRGetScreenResources (ClientPtr client) +{ + REQUEST(xRRGetScreenResourcesReq); + xRRGetScreenResourcesReply rep; + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + CARD8 *extra; + unsigned long extraLen; + int i, n, rc; + RRCrtc *crtcs; + RROutput *outputs; + xRRModeInfo *modeinfos; + CARD8 *names; + + REQUEST_SIZE_MATCH(xRRGetScreenResourcesReq); + #ifndef NXAGENT_SERVER + rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); + #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)) + return BadAlloc; + + 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; + extra = NULL; + extraLen = 0; + } + else + { + RRModePtr *modes; + int num_modes; + + modes = RRModesForScreen (pScreen, &num_modes); + 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; + + 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)); + + extraLen = rep.length << 2; + if (extraLen) + { + extra = xalloc (extraLen); + if (!extra) + { + xfree (modes); + return BadAlloc; + } + } + else + extra = NULL; + + crtcs = (RRCrtc *) extra; + outputs = (RROutput *) (crtcs + pScrPriv->numCrtcs); + modeinfos = (xRRModeInfo *) (outputs + pScrPriv->numOutputs); + names = (CARD8 *) (modeinfos + num_modes); + + 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); + } + + for (i = 0; i < num_modes; i++) + { + RRModePtr mode = modes[i]; + modeinfos[i] = mode->mode; + if (client->swapped) + { + 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); + } + memcpy (names, mode->name, + mode->mode.nameLength); + names += mode->mode.nameLength; + } + xfree (modes); + assert (((((char *) names - (char *) extra) + 3) >> 2) == 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 client->noClientException; +} + +typedef struct _RR10Data { + RRScreenSizePtr sizes; + int nsize; + int nrefresh; + int size; + CARD16 refresh; +} RR10DataRec, *RR10DataPtr; + +/* + * Convert 1.2 monitor data into 1.0 screen data + */ +static RR10DataPtr +RR10GetData (ScreenPtr pScreen, RROutputPtr output) +{ + RR10DataPtr data; + RRScreenSizePtr size; + int nmode = output->numModes + output->numUserModes; + int o, os, l, r; + RRScreenRatePtr refresh; + CARD16 vRefresh; + RRModePtr mode; + Bool *used; + + /* Make sure there is plenty of space for any combination */ + data = malloc (sizeof (RR10DataRec) + + sizeof (RRScreenSize) * nmode + + sizeof (RRScreenRate) * nmode + + sizeof (Bool) * nmode); + if (!data) + return NULL; + size = (RRScreenSizePtr) (data + 1); + refresh = (RRScreenRatePtr) (size + nmode); + used = (Bool *) (refresh + nmode); + memset (used, '\0', sizeof (Bool) * nmode); + data->sizes = size; + data->nsize = 0; + data->nrefresh = 0; + data->size = 0; + data->refresh = 0; + + /* + * find modes not yet listed + */ + for (o = 0; o < output->numModes + output->numUserModes; o++) + { + if (used[o]) continue; + + if (o < output->numModes) + mode = output->modes[o]; + else + mode = output->userModes[o - output->numModes]; + + l = data->nsize; + size[l].id = data->nsize; + size[l].width = mode->mode.width; + size[l].height = mode->mode.height; + if (output->mmWidth && output->mmHeight) { + size[l].mmWidth = output->mmWidth; + size[l].mmHeight = output->mmHeight; + } else { + size[l].mmWidth = pScreen->mmWidth; + size[l].mmHeight = pScreen->mmHeight; + } + size[l].nRates = 0; + size[l].pRates = &refresh[data->nrefresh]; + data->nsize++; + + /* + * Find all modes with matching size + */ + for (os = o; os < output->numModes + output->numUserModes; os++) + { + if (os < output->numModes) + mode = output->modes[os]; + else + mode = output->userModes[os - output->numModes]; + if (mode->mode.width == size[l].width && + mode->mode.height == size[l].height) + { + vRefresh = RRVerticalRefresh (&mode->mode); + used[os] = TRUE; + + for (r = 0; r < size[l].nRates; r++) + if (vRefresh == size[l].pRates[r].rate) + break; + if (r == size[l].nRates) + { + size[l].pRates[r].rate = vRefresh; + size[l].pRates[r].mode = mode; + size[l].nRates++; + data->nrefresh++; + } + if (mode == output->crtc->mode) + { + data->size = l; + data->refresh = vRefresh; + } + } + } + } + return data; +} + +int +ProcRRGetScreenInfo (ClientPtr client) +{ + REQUEST(xRRGetScreenInfoReq); + xRRGetScreenInfoReply rep; + WindowPtr pWin; + int n, rc; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + CARD8 *extra; + unsigned long extraLen; + RROutputPtr output; + + REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); + #ifndef NXAGENT_SERVER + rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); + #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)) + 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; + extra = 0; + extraLen = 0; + } + else + { + int i, j; + xScreenSizes *size; + CARD16 *rates; + CARD8 *data8; + Bool has_rate = RRClientKnowsRates (client); + RR10DataPtr pData; + RRScreenSizePtr pSize; + + pData = RR10GetData (pScreen, output); + 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; + + extraLen = (rep.nSizes * sizeof (xScreenSizes) + + rep.nrateEnts * sizeof (CARD16)); + + if (extraLen) + { + extra = (CARD8 *) xalloc (extraLen); + if (!extra) + { + xfree (pData); + return BadAlloc; + } + } + else + extra = NULL; + + /* + * First comes the size information + */ + size = (xScreenSizes *) extra; + rates = (CARD16 *) (size + rep.nSizes); + for (i = 0; i < pData->nsize; i++) + { + pSize = &pData->sizes[i]; + size->widthInPixels = pSize->width; + size->heightInPixels = pSize->height; + size->widthInMillimeters = pSize->mmWidth; + size->heightInMillimeters = pSize->mmHeight; + if (client->swapped) + { + swaps (&size->widthInPixels, n); + swaps (&size->heightInPixels, n); + swaps (&size->widthInMillimeters, n); + swaps (&size->heightInMillimeters, n); + } + size++; + if (has_rate) + { + *rates = pSize->nRates; + if (client->swapped) + { + swaps (rates, n); + } + rates++; + for (j = 0; j < pSize->nRates; j++) + { + *rates = pSize->pRates[j].rate; + if (client->swapped) + { + swaps (rates, n); + } + rates++; + } + } + } + xfree (pData); + + data8 = (CARD8 *) rates; + + if (data8 - (CARD8 *) extra != extraLen) + FatalError ("RRGetScreenInfo bad extra len %ld != %ld\n", + (unsigned long)(data8 - (CARD8 *) extra), extraLen); + rep.length = (extraLen + 3) >> 2; + } + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.timestamp, n); + swaps(&rep.rotation, n); + swaps(&rep.nSizes, n); + swaps(&rep.sizeID, n); + swaps(&rep.rate, n); + swaps(&rep.nrateEnts, n); + } + WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *)&rep); + if (extraLen) + { + WriteToClient (client, extraLen, (char *) extra); + xfree (extra); + } + return (client->noClientException); +} + +int +ProcRRSetScreenConfig (ClientPtr client) +{ + REQUEST(xRRSetScreenConfigReq); + xRRSetScreenConfigReply rep; + DrawablePtr pDraw; + int n, rc; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + TimeStamp time; + int i; + Rotation rotation; + int rate; + Bool has_rate; + RROutputPtr output; + RRCrtcPtr crtc; + RRModePtr mode; + RR10DataPtr pData = NULL; + RRScreenSizePtr pSize; + int width, height; + + UpdateCurrentTime (); + + if (RRClientKnowsRates (client)) + { + REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); + has_rate = TRUE; + } + else + { + REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); + has_rate = FALSE; + } + + #ifndef NXAGENT_SERVER + rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess); + #else + pDraw = SecurityLookupDrawable(stuff->drawable, client, SecurityWriteAccess); + rc = pDraw ? Success : BadDrawable; + #endif + if (rc != Success) + return rc; + + pScreen = pDraw->pScreen; + + pScrPriv = rrGetScrPriv(pScreen); + + time = ClientTimeToServerTime(stuff->timestamp); + + if (!pScrPriv) + { + time = currentTime; + rep.status = RRSetConfigFailed; + goto sendReply; + } + if (!RRGetInfo (pScreen)) + return BadAlloc; + + output = RRFirstOutput (pScreen); + if (!output) + { + time = currentTime; + rep.status = RRSetConfigFailed; + goto sendReply; + } + + crtc = output->crtc; + + /* + * If the client's config timestamp is not the same as the last config + * timestamp, then the config information isn't up-to-date and + * can't even be validated. + * + * Note that the client only knows about the milliseconds part of the + * timestamp, so using CompareTimeStamps here would cause randr to suddenly + * stop working after several hours have passed (freedesktop bug #6502). + */ + if (stuff->configTimestamp != pScrPriv->lastConfigTime.milliseconds) + { + rep.status = RRSetConfigInvalidConfigTime; + goto sendReply; + } + + pData = RR10GetData (pScreen, output); + if (!pData) + return BadAlloc; + + if (stuff->sizeID >= pData->nsize) + { + /* + * Invalid size ID + */ + client->errorValue = stuff->sizeID; + xfree (pData); + return BadValue; + } + pSize = &pData->sizes[stuff->sizeID]; + + /* + * Validate requested rotation + */ + rotation = (Rotation) stuff->rotation; + + /* test the rotation bits only! */ + switch (rotation & 0xf) { + case RR_Rotate_0: + case RR_Rotate_90: + case RR_Rotate_180: + case RR_Rotate_270: + break; + default: + /* + * Invalid rotation + */ + client->errorValue = stuff->rotation; + xfree (pData); + return BadValue; + } + + if ((~crtc->rotations) & rotation) + { + /* + * requested rotation or reflection not supported by screen + */ + client->errorValue = stuff->rotation; + xfree (pData); + return BadMatch; + } + + /* + * Validate requested refresh + */ + if (has_rate) + rate = (int) stuff->rate; + else + rate = 0; + + if (rate) + { + for (i = 0; i < pSize->nRates; i++) + { + if (pSize->pRates[i].rate == rate) + break; + } + if (i == pSize->nRates) + { + /* + * Invalid rate + */ + client->errorValue = rate; + xfree (pData); + return BadValue; + } + mode = pSize->pRates[i].mode; + } + else + mode = pSize->pRates[0].mode; + + /* + * 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 the screen size is changing, adjust all of the other outputs + * to fit the new size, mirroring as much as possible + */ + 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 != 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; + /* XXX recover from failure */ + goto sendReply; + } + } + if (!RRScreenSizeSet (pScreen, width, height, + pScreen->mmWidth, pScreen->mmHeight)) + { + rep.status = RRSetConfigFailed; + /* XXX recover from failure */ + goto sendReply; + } + } + + if (!RRCrtcSet (crtc, mode, 0, 0, stuff->rotation, 1, &output)) + rep.status = RRSetConfigFailed; + #ifndef NXAGENT_SERVER /* Bug 21987 */ + else + rep.status = RRSetConfigSuccess; + #else + else { + rep.status = RRSetConfigSuccess; + pScrPriv->lastSetTime = time; + } + #endif + + /* + * XXX Configure other crtcs to mirror as much as possible + */ + +sendReply: + + if (pData) + xfree (pData); + + rep.type = X_Reply; + /* rep.status has already been filled in */ + rep.length = 0; + rep.sequenceNumber = client->sequence; + + rep.newTimestamp = pScrPriv->lastSetTime.milliseconds; + rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds; + rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id; + + if (client->swapped) + { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.newTimestamp, n); + swapl(&rep.newConfigTimestamp, n); + swapl(&rep.root, n); + } + WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *)&rep); + + return (client->noClientException); +} + +static CARD16 +RR10CurrentSizeID (ScreenPtr pScreen) +{ + CARD16 sizeID = 0xffff; + RROutputPtr output = RRFirstOutput (pScreen); + + if (output) + { + RR10DataPtr data = RR10GetData (pScreen, output); + if (data) + { + int i; + for (i = 0; i < data->nsize; i++) + if (data->sizes[i].width == pScreen->width && + data->sizes[i].height == pScreen->height) + { + sizeID = (CARD16) i; + break; + } + xfree (data); + } + } + return sizeID; +} diff --git a/programs/Xserver/randr/rrscreen.c.X.original b/programs/Xserver/randr/rrscreen.c.X.original new file mode 100644 index 0000000..f391973 --- /dev/null +++ b/programs/Xserver/randr/rrscreen.c.X.original @@ -0,0 +1,981 @@ +/* + * 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" + +extern char *ConnectionInfo; + +static int padlength[4] = {0, 3, 2, 1}; + +static CARD16 +RR10CurrentSizeID (ScreenPtr pScreen); + +/* + * Edit connection information block so that new clients + * see the current screen size on connect + */ +static void +RREditConnectionInfo (ScreenPtr pScreen) +{ + xConnSetup *connSetup; + char *vendor; + xPixmapFormat *formats; + xWindowRoot *root; + xDepth *depth; + xVisualType *visual; + int screen = 0; + int d; + + connSetup = (xConnSetup *) ConnectionInfo; + vendor = (char *) connSetup + sizeof (xConnSetup); + formats = (xPixmapFormat *) ((char *) vendor + + connSetup->nbytesVendor + + padlength[connSetup->nbytesVendor & 3]); + root = (xWindowRoot *) ((char *) formats + + sizeof (xPixmapFormat) * screenInfo.numPixmapFormats); + while (screen != pScreen->myNum) + { + depth = (xDepth *) ((char *) root + + sizeof (xWindowRoot)); + for (d = 0; d < root->nDepths; d++) + { + visual = (xVisualType *) ((char *) depth + + sizeof (xDepth)); + depth = (xDepth *) ((char *) visual + + depth->nVisuals * sizeof (xVisualType)); + } + root = (xWindowRoot *) ((char *) depth); + screen++; + } + root->pixWidth = pScreen->width; + root->pixHeight = pScreen->height; + root->mmWidth = pScreen->mmWidth; + root->mmHeight = pScreen->mmHeight; +} + +void +RRSendConfigNotify (ScreenPtr pScreen) +{ + WindowPtr pWin = WindowTable[pScreen->myNum]; + xEvent event; + + 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); +} + +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; +#endif + + se.sequenceNumber = client->sequence; + se.sizeID = RR10CurrentSizeID (pScreen); + + if (se.rotation & (RR_Rotate_90 | RR_Rotate_270)) { + se.widthInPixels = pScreen->height; + se.heightInPixels = pScreen->width; + se.widthInMillimeters = pScreen->mmHeight; + se.heightInMillimeters = pScreen->mmWidth; + } else { + se.widthInPixels = pScreen->width; + se.heightInPixels = pScreen->height; + se.widthInMillimeters = pScreen->mmWidth; + se.heightInMillimeters = pScreen->mmHeight; + } + + WriteEventsToClient (client, 1, (xEvent *) &se); +} + +/* + * Notify the extension that the screen size has been changed. + * The driver is responsible for calling this whenever it has changed + * the size of the screen + */ +void +RRScreenSizeNotify (ScreenPtr pScreen) +{ + rrScrPriv(pScreen); + /* + * Deliver ConfigureNotify events when root changes + * pixel size + */ + if (pScrPriv->width == pScreen->width && + pScrPriv->height == pScreen->height && + pScrPriv->mmWidth == pScreen->mmWidth && + pScrPriv->mmHeight == pScreen->mmHeight) + return; + + pScrPriv->width = pScreen->width; + pScrPriv->height = pScreen->height; + pScrPriv->mmWidth = pScreen->mmWidth; + pScrPriv->mmHeight = pScreen->mmHeight; + pScrPriv->changed = TRUE; +/* pScrPriv->sizeChanged = TRUE; */ + + RRTellChanged (pScreen); + RRSendConfigNotify (pScreen); + RREditConnectionInfo (pScreen); + + RRPointerScreenConfigured (pScreen); + /* + * Fix pointer bounds and location + */ + ScreenRestructured (pScreen); +} + +/* + * Request that the screen be resized + */ +Bool +RRScreenSizeSet (ScreenPtr pScreen, + CARD16 width, + CARD16 height, + CARD32 mmWidth, + CARD32 mmHeight) +{ + rrScrPriv(pScreen); + +#if RANDR_12_INTERFACE + if (pScrPriv->rrScreenSetSize) + { + return (*pScrPriv->rrScreenSetSize) (pScreen, + width, height, + mmWidth, mmHeight); + } +#endif +#if RANDR_10_INTERFACE + if (pScrPriv->rrSetConfig) + { + return TRUE; /* can't set size separately */ + } +#endif + return FALSE; +} + +/* + * Retrieve valid screen size range + */ +int +ProcRRGetScreenSizeRange (ClientPtr client) +{ + REQUEST(xRRGetScreenSizeRangeReq); + xRRGetScreenSizeRangeReply rep; + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + int rc; + + REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); + rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); + 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; + + if (pScrPriv) + { + if (!RRGetInfo (pScreen)) + return BadAlloc; + rep.minWidth = pScrPriv->minWidth; + rep.minHeight = pScrPriv->minHeight; + rep.maxWidth = pScrPriv->maxWidth; + rep.maxHeight = pScrPriv->maxHeight; + } + else + { + rep.maxWidth = rep.minWidth = pScreen->width; + rep.maxHeight = rep.minHeight = pScreen->height; + } + if (client->swapped) + { + int n; + + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.minWidth, n); + swaps(&rep.minHeight, n); + swaps(&rep.maxWidth, n); + swaps(&rep.maxHeight, n); + } + WriteToClient(client, sizeof(xRRGetScreenSizeRangeReply), (char *)&rep); + return (client->noClientException); +} + +int +ProcRRSetScreenSize (ClientPtr client) +{ + REQUEST(xRRSetScreenSizeReq); + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + int i, rc; + + REQUEST_SIZE_MATCH(xRRSetScreenSizeReq); + rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); + if (rc != Success) + return rc; + + pScreen = pWin->drawable.pScreen; + pScrPriv = rrGetScrPriv(pScreen); + if (stuff->width < pScrPriv->minWidth || pScrPriv->maxWidth < stuff->width) + { + client->errorValue = stuff->width; + return BadValue; + } + if (stuff->height < pScrPriv->minHeight || + pScrPriv->maxHeight < stuff->height) + { + client->errorValue = stuff->height; + return BadValue; + } + for (i = 0; i < pScrPriv->numCrtcs; i++) + { + RRCrtcPtr crtc = pScrPriv->crtcs[i]; + RRModePtr mode = crtc->mode; + if (mode) + { + int source_width = mode->mode.width; + int source_height = mode->mode.height; + Rotation rotation = crtc->rotation; + + if (rotation == RR_Rotate_90 || rotation == RR_Rotate_270) + { + source_width = mode->mode.height; + source_height = mode->mode.width; + } + + if (crtc->x + source_width > stuff->width || + crtc->y + source_height > stuff->height) + return BadMatch; + } + } + if (stuff->widthInMillimeters == 0 || stuff->heightInMillimeters == 0) + { + client->errorValue = 0; + return BadValue; + } + if (!RRScreenSizeSet (pScreen, + stuff->width, stuff->height, + stuff->widthInMillimeters, + stuff->heightInMillimeters)) + { + return BadMatch; + } + return Success; +} + +int +ProcRRGetScreenResources (ClientPtr client) +{ + REQUEST(xRRGetScreenResourcesReq); + xRRGetScreenResourcesReply rep; + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + CARD8 *extra; + unsigned long extraLen; + int i, n, rc; + RRCrtc *crtcs; + RROutput *outputs; + xRRModeInfo *modeinfos; + CARD8 *names; + + REQUEST_SIZE_MATCH(xRRGetScreenResourcesReq); + rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); + if (rc != Success) + return rc; + + pScreen = pWin->drawable.pScreen; + pScrPriv = rrGetScrPriv(pScreen); + rep.pad = 0; + + if (pScrPriv) + if (!RRGetInfo (pScreen)) + return BadAlloc; + + 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; + extra = NULL; + extraLen = 0; + } + else + { + RRModePtr *modes; + int num_modes; + + modes = RRModesForScreen (pScreen, &num_modes); + 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; + + 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)); + + extraLen = rep.length << 2; + if (extraLen) + { + extra = xalloc (extraLen); + if (!extra) + { + xfree (modes); + return BadAlloc; + } + } + else + extra = NULL; + + crtcs = (RRCrtc *) extra; + outputs = (RROutput *) (crtcs + pScrPriv->numCrtcs); + modeinfos = (xRRModeInfo *) (outputs + pScrPriv->numOutputs); + names = (CARD8 *) (modeinfos + num_modes); + + 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); + } + + for (i = 0; i < num_modes; i++) + { + RRModePtr mode = modes[i]; + modeinfos[i] = mode->mode; + if (client->swapped) + { + 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); + } + memcpy (names, mode->name, + mode->mode.nameLength); + names += mode->mode.nameLength; + } + xfree (modes); + assert (((((char *) names - (char *) extra) + 3) >> 2) == 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 client->noClientException; +} + +typedef struct _RR10Data { + RRScreenSizePtr sizes; + int nsize; + int nrefresh; + int size; + CARD16 refresh; +} RR10DataRec, *RR10DataPtr; + +/* + * Convert 1.2 monitor data into 1.0 screen data + */ +static RR10DataPtr +RR10GetData (ScreenPtr pScreen, RROutputPtr output) +{ + RR10DataPtr data; + RRScreenSizePtr size; + int nmode = output->numModes + output->numUserModes; + int o, os, l, r; + RRScreenRatePtr refresh; + CARD16 vRefresh; + RRModePtr mode; + Bool *used; + + /* Make sure there is plenty of space for any combination */ + data = malloc (sizeof (RR10DataRec) + + sizeof (RRScreenSize) * nmode + + sizeof (RRScreenRate) * nmode + + sizeof (Bool) * nmode); + if (!data) + return NULL; + size = (RRScreenSizePtr) (data + 1); + refresh = (RRScreenRatePtr) (size + nmode); + used = (Bool *) (refresh + nmode); + memset (used, '\0', sizeof (Bool) * nmode); + data->sizes = size; + data->nsize = 0; + data->nrefresh = 0; + data->size = 0; + data->refresh = 0; + + /* + * find modes not yet listed + */ + for (o = 0; o < output->numModes + output->numUserModes; o++) + { + if (used[o]) continue; + + if (o < output->numModes) + mode = output->modes[o]; + else + mode = output->userModes[o - output->numModes]; + + l = data->nsize; + size[l].id = data->nsize; + size[l].width = mode->mode.width; + size[l].height = mode->mode.height; + if (output->mmWidth && output->mmHeight) { + size[l].mmWidth = output->mmWidth; + size[l].mmHeight = output->mmHeight; + } else { + size[l].mmWidth = pScreen->mmWidth; + size[l].mmHeight = pScreen->mmHeight; + } + size[l].nRates = 0; + size[l].pRates = &refresh[data->nrefresh]; + data->nsize++; + + /* + * Find all modes with matching size + */ + for (os = o; os < output->numModes + output->numUserModes; os++) + { + if (os < output->numModes) + mode = output->modes[os]; + else + mode = output->userModes[os - output->numModes]; + if (mode->mode.width == size[l].width && + mode->mode.height == size[l].height) + { + vRefresh = RRVerticalRefresh (&mode->mode); + used[os] = TRUE; + + for (r = 0; r < size[l].nRates; r++) + if (vRefresh == size[l].pRates[r].rate) + break; + if (r == size[l].nRates) + { + size[l].pRates[r].rate = vRefresh; + size[l].pRates[r].mode = mode; + size[l].nRates++; + data->nrefresh++; + } + if (mode == output->crtc->mode) + { + data->size = l; + data->refresh = vRefresh; + } + } + } + } + return data; +} + +int +ProcRRGetScreenInfo (ClientPtr client) +{ + REQUEST(xRRGetScreenInfoReq); + xRRGetScreenInfoReply rep; + WindowPtr pWin; + int n, rc; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + CARD8 *extra; + unsigned long extraLen; + RROutputPtr output; + + REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); + rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); + if (rc != Success) + return rc; + + pScreen = pWin->drawable.pScreen; + pScrPriv = rrGetScrPriv(pScreen); + rep.pad = 0; + + if (pScrPriv) + if (!RRGetInfo (pScreen)) + 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; + extra = 0; + extraLen = 0; + } + else + { + int i, j; + xScreenSizes *size; + CARD16 *rates; + CARD8 *data8; + Bool has_rate = RRClientKnowsRates (client); + RR10DataPtr pData; + RRScreenSizePtr pSize; + + pData = RR10GetData (pScreen, output); + 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; + + extraLen = (rep.nSizes * sizeof (xScreenSizes) + + rep.nrateEnts * sizeof (CARD16)); + + if (extraLen) + { + extra = (CARD8 *) xalloc (extraLen); + if (!extra) + { + xfree (pData); + return BadAlloc; + } + } + else + extra = NULL; + + /* + * First comes the size information + */ + size = (xScreenSizes *) extra; + rates = (CARD16 *) (size + rep.nSizes); + for (i = 0; i < pData->nsize; i++) + { + pSize = &pData->sizes[i]; + size->widthInPixels = pSize->width; + size->heightInPixels = pSize->height; + size->widthInMillimeters = pSize->mmWidth; + size->heightInMillimeters = pSize->mmHeight; + if (client->swapped) + { + swaps (&size->widthInPixels, n); + swaps (&size->heightInPixels, n); + swaps (&size->widthInMillimeters, n); + swaps (&size->heightInMillimeters, n); + } + size++; + if (has_rate) + { + *rates = pSize->nRates; + if (client->swapped) + { + swaps (rates, n); + } + rates++; + for (j = 0; j < pSize->nRates; j++) + { + *rates = pSize->pRates[j].rate; + if (client->swapped) + { + swaps (rates, n); + } + rates++; + } + } + } + xfree (pData); + + data8 = (CARD8 *) rates; + + if (data8 - (CARD8 *) extra != extraLen) + FatalError ("RRGetScreenInfo bad extra len %ld != %ld\n", + (unsigned long)(data8 - (CARD8 *) extra), extraLen); + rep.length = (extraLen + 3) >> 2; + } + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.timestamp, n); + swaps(&rep.rotation, n); + swaps(&rep.nSizes, n); + swaps(&rep.sizeID, n); + swaps(&rep.rate, n); + swaps(&rep.nrateEnts, n); + } + WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *)&rep); + if (extraLen) + { + WriteToClient (client, extraLen, (char *) extra); + xfree (extra); + } + return (client->noClientException); +} + +int +ProcRRSetScreenConfig (ClientPtr client) +{ + REQUEST(xRRSetScreenConfigReq); + xRRSetScreenConfigReply rep; + DrawablePtr pDraw; + int n, rc; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + TimeStamp time; + int i; + Rotation rotation; + int rate; + Bool has_rate; + RROutputPtr output; + RRCrtcPtr crtc; + RRModePtr mode; + RR10DataPtr pData = NULL; + RRScreenSizePtr pSize; + int width, height; + + UpdateCurrentTime (); + + if (RRClientKnowsRates (client)) + { + REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); + has_rate = TRUE; + } + else + { + REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); + has_rate = FALSE; + } + + rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess); + if (rc != Success) + return rc; + + pScreen = pDraw->pScreen; + + pScrPriv = rrGetScrPriv(pScreen); + + time = ClientTimeToServerTime(stuff->timestamp); + + if (!pScrPriv) + { + time = currentTime; + rep.status = RRSetConfigFailed; + goto sendReply; + } + if (!RRGetInfo (pScreen)) + return BadAlloc; + + output = RRFirstOutput (pScreen); + if (!output) + { + time = currentTime; + rep.status = RRSetConfigFailed; + goto sendReply; + } + + crtc = output->crtc; + + /* + * If the client's config timestamp is not the same as the last config + * timestamp, then the config information isn't up-to-date and + * can't even be validated. + * + * Note that the client only knows about the milliseconds part of the + * timestamp, so using CompareTimeStamps here would cause randr to suddenly + * stop working after several hours have passed (freedesktop bug #6502). + */ + if (stuff->configTimestamp != pScrPriv->lastConfigTime.milliseconds) + { + rep.status = RRSetConfigInvalidConfigTime; + goto sendReply; + } + + pData = RR10GetData (pScreen, output); + if (!pData) + return BadAlloc; + + if (stuff->sizeID >= pData->nsize) + { + /* + * Invalid size ID + */ + client->errorValue = stuff->sizeID; + xfree (pData); + return BadValue; + } + pSize = &pData->sizes[stuff->sizeID]; + + /* + * Validate requested rotation + */ + rotation = (Rotation) stuff->rotation; + + /* test the rotation bits only! */ + switch (rotation & 0xf) { + case RR_Rotate_0: + case RR_Rotate_90: + case RR_Rotate_180: + case RR_Rotate_270: + break; + default: + /* + * Invalid rotation + */ + client->errorValue = stuff->rotation; + xfree (pData); + return BadValue; + } + + if ((~crtc->rotations) & rotation) + { + /* + * requested rotation or reflection not supported by screen + */ + client->errorValue = stuff->rotation; + xfree (pData); + return BadMatch; + } + + /* + * Validate requested refresh + */ + if (has_rate) + rate = (int) stuff->rate; + else + rate = 0; + + if (rate) + { + for (i = 0; i < pSize->nRates; i++) + { + if (pSize->pRates[i].rate == rate) + break; + } + if (i == pSize->nRates) + { + /* + * Invalid rate + */ + client->errorValue = rate; + xfree (pData); + return BadValue; + } + mode = pSize->pRates[i].mode; + } + else + mode = pSize->pRates[0].mode; + + /* + * 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 the screen size is changing, adjust all of the other outputs + * to fit the new size, mirroring as much as possible + */ + 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 != 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; + /* XXX recover from failure */ + goto sendReply; + } + } + if (!RRScreenSizeSet (pScreen, width, height, + pScreen->mmWidth, pScreen->mmHeight)) + { + rep.status = RRSetConfigFailed; + /* XXX recover from failure */ + goto sendReply; + } + } + + if (!RRCrtcSet (crtc, mode, 0, 0, stuff->rotation, 1, &output)) + rep.status = RRSetConfigFailed; + else + rep.status = RRSetConfigSuccess; + + /* + * XXX Configure other crtcs to mirror as much as possible + */ + +sendReply: + + if (pData) + xfree (pData); + + rep.type = X_Reply; + /* rep.status has already been filled in */ + rep.length = 0; + rep.sequenceNumber = client->sequence; + + rep.newTimestamp = pScrPriv->lastSetTime.milliseconds; + rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds; + rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id; + + if (client->swapped) + { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.newTimestamp, n); + swapl(&rep.newConfigTimestamp, n); + swapl(&rep.root, n); + } + WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *)&rep); + + return (client->noClientException); +} + +static CARD16 +RR10CurrentSizeID (ScreenPtr pScreen) +{ + CARD16 sizeID = 0xffff; + RROutputPtr output = RRFirstOutput (pScreen); + + if (output) + { + RR10DataPtr data = RR10GetData (pScreen, output); + if (data) + { + int i; + for (i = 0; i < data->nsize; i++) + if (data->sizes[i].width == pScreen->width && + data->sizes[i].height == pScreen->height) + { + sizeID = (CARD16) i; + break; + } + xfree (data); + } + } + return sizeID; +} diff --git a/programs/Xserver/randr/rrsdispatch.c b/programs/Xserver/randr/rrsdispatch.c new file mode 100644 index 0000000..80d16b7 --- /dev/null +++ b/programs/Xserver/randr/rrsdispatch.c @@ -0,0 +1,398 @@ +/* + * 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" + +static int +SProcRRQueryVersion (ClientPtr client) +{ + register int n; + REQUEST(xRRQueryVersionReq); + + swaps(&stuff->length, n); + swapl(&stuff->majorVersion, n); + swapl(&stuff->minorVersion, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetScreenInfo (ClientPtr client) +{ + register int n; + REQUEST(xRRGetScreenInfoReq); + + swaps(&stuff->length, n); + swapl(&stuff->window, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRSetScreenConfig (ClientPtr client) +{ + register int n; + REQUEST(xRRSetScreenConfigReq); + + if (RRClientKnowsRates (client)) + { + REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); + swaps (&stuff->rate, n); + } + else + { + REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); + } + + swaps(&stuff->length, n); + swapl(&stuff->drawable, n); + swapl(&stuff->timestamp, n); + swaps(&stuff->sizeID, n); + swaps(&stuff->rotation, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRSelectInput (ClientPtr client) +{ + register int n; + REQUEST(xRRSelectInputReq); + + swaps(&stuff->length, n); + swapl(&stuff->window, n); + swaps(&stuff->enable, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetScreenSizeRange (ClientPtr client) +{ + int n; + REQUEST(xRRGetScreenSizeRangeReq); + + REQUEST_SIZE_MATCH(xRRGetScreenSizeRangeReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRSetScreenSize (ClientPtr client) +{ + int n; + REQUEST(xRRSetScreenSizeReq); + + REQUEST_SIZE_MATCH(xRRSetScreenSizeReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + swaps(&stuff->width, n); + swaps(&stuff->height, n); + swapl(&stuff->widthInMillimeters, n); + swapl(&stuff->heightInMillimeters, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetScreenResources (ClientPtr client) +{ + int n; + REQUEST(xRRGetScreenResourcesReq); + + REQUEST_SIZE_MATCH(xRRGetScreenResourcesReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetOutputInfo (ClientPtr client) +{ + int n; + REQUEST(xRRGetOutputInfoReq);; + + REQUEST_SIZE_MATCH(xRRGetOutputInfoReq); + swaps(&stuff->length, n); + swapl(&stuff->output, n); + swapl(&stuff->configTimestamp, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRListOutputProperties (ClientPtr client) +{ + int n; + REQUEST(xRRListOutputPropertiesReq); + + REQUEST_SIZE_MATCH(xRRListOutputPropertiesReq); + swaps(&stuff->length, n); + swapl(&stuff->output, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRQueryOutputProperty (ClientPtr client) +{ + int n; + REQUEST(xRRQueryOutputPropertyReq); + + REQUEST_SIZE_MATCH(xRRQueryOutputPropertyReq); + swaps(&stuff->length, n); + swapl(&stuff->output, n); + swapl(&stuff->property, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRConfigureOutputProperty (ClientPtr client) +{ + int n; + REQUEST(xRRConfigureOutputPropertyReq); + + swaps(&stuff->length, n); + swapl(&stuff->output, n); + swapl(&stuff->property, n); + SwapRestL(stuff); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRChangeOutputProperty (ClientPtr client) +{ + int n; + REQUEST(xRRChangeOutputPropertyReq); + + REQUEST_AT_LEAST_SIZE (xRRChangeOutputPropertyReq); + swaps(&stuff->length, n); + swapl(&stuff->output, 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; + default: + client->errorValue = stuff->format; + return BadValue; + } + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRDeleteOutputProperty (ClientPtr client) +{ + int n; + REQUEST(xRRDeleteOutputPropertyReq); + + REQUEST_SIZE_MATCH(xRRDeleteOutputPropertyReq); + swaps(&stuff->length, n); + swapl(&stuff->output, n); + swapl(&stuff->property, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetOutputProperty (ClientPtr client) +{ + int n; + REQUEST(xRRGetOutputPropertyReq); + + REQUEST_SIZE_MATCH(xRRGetOutputPropertyReq); + swaps(&stuff->length, n); + swapl(&stuff->output, n); + swapl(&stuff->property, n); + swapl(&stuff->type, n); + swapl(&stuff->longOffset, n); + swapl(&stuff->longLength, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRCreateMode (ClientPtr client) +{ + int n; + xRRModeInfo *modeinfo; + REQUEST(xRRCreateModeReq); + + REQUEST_AT_LEAST_SIZE(xRRCreateModeReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + + modeinfo = &stuff->modeInfo; + swapl(&modeinfo->id, n); + swaps(&modeinfo->width, n); + swaps(&modeinfo->height, n); + swapl(&modeinfo->dotClock, n); + swaps(&modeinfo->hSyncStart, n); + swaps(&modeinfo->hSyncEnd, n); + swaps(&modeinfo->hTotal, n); + swaps(&modeinfo->vSyncStart, n); + swaps(&modeinfo->vSyncEnd, n); + swaps(&modeinfo->vTotal, n); + swaps(&modeinfo->nameLength, n); + swapl(&modeinfo->modeFlags, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRDestroyMode (ClientPtr client) +{ + int n; + REQUEST(xRRDestroyModeReq); + + REQUEST_SIZE_MATCH(xRRDestroyModeReq); + swaps(&stuff->length, n); + swapl(&stuff->mode, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRAddOutputMode (ClientPtr client) +{ + int n; + REQUEST(xRRAddOutputModeReq); + + REQUEST_SIZE_MATCH(xRRAddOutputModeReq); + swaps(&stuff->length, n); + swapl(&stuff->output, n); + swapl(&stuff->mode, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRDeleteOutputMode (ClientPtr client) +{ + int n; + REQUEST(xRRDeleteOutputModeReq); + + REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq); + swaps(&stuff->length, n); + swapl(&stuff->output, n); + swapl(&stuff->mode, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetCrtcInfo (ClientPtr client) +{ + int n; + REQUEST(xRRGetCrtcInfoReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + swapl(&stuff->configTimestamp, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRSetCrtcConfig (ClientPtr client) +{ + int n; + REQUEST(xRRSetCrtcConfigReq); + + REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + swapl(&stuff->timestamp, n); + swapl(&stuff->configTimestamp, n); + swaps(&stuff->x, n); + swaps(&stuff->y, n); + swapl(&stuff->mode, n); + swaps(&stuff->rotation, n); + SwapRestL(stuff); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetCrtcGammaSize (ClientPtr client) +{ + int n; + REQUEST(xRRGetCrtcGammaSizeReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetCrtcGamma (ClientPtr client) +{ + int n; + REQUEST(xRRGetCrtcGammaReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRSetCrtcGamma (ClientPtr client) +{ + int n; + REQUEST(xRRSetCrtcGammaReq); + + REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + swaps(&stuff->size, n); + SwapRestS(stuff); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = { + SProcRRQueryVersion, /* 0 */ +/* we skip 1 to make old clients fail pretty immediately */ + NULL, /* 1 SProcRandrOldGetScreenInfo */ +/* V1.0 apps share the same set screen config request id */ + SProcRRSetScreenConfig, /* 2 */ + NULL, /* 3 SProcRandrOldScreenChangeSelectInput */ +/* 3 used to be ScreenChangeSelectInput; deprecated */ + SProcRRSelectInput, /* 4 */ + SProcRRGetScreenInfo, /* 5 */ +/* V1.2 additions */ + SProcRRGetScreenSizeRange, /* 6 */ + SProcRRSetScreenSize, /* 7 */ + SProcRRGetScreenResources, /* 8 */ + SProcRRGetOutputInfo, /* 9 */ + SProcRRListOutputProperties,/* 10 */ + SProcRRQueryOutputProperty, /* 11 */ + SProcRRConfigureOutputProperty, /* 12 */ + SProcRRChangeOutputProperty,/* 13 */ + SProcRRDeleteOutputProperty,/* 14 */ + SProcRRGetOutputProperty, /* 15 */ + SProcRRCreateMode, /* 16 */ + SProcRRDestroyMode, /* 17 */ + SProcRRAddOutputMode, /* 18 */ + SProcRRDeleteOutputMode, /* 19 */ + SProcRRGetCrtcInfo, /* 20 */ + SProcRRSetCrtcConfig, /* 21 */ + SProcRRGetCrtcGammaSize, /* 22 */ + SProcRRGetCrtcGamma, /* 23 */ + SProcRRSetCrtcGamma, /* 24 */ +}; + diff --git a/programs/Xserver/randr/rrxinerama.c b/programs/Xserver/randr/rrxinerama.c new file mode 100644 index 0000000..9f11279 --- /dev/null +++ b/programs/Xserver/randr/rrxinerama.c @@ -0,0 +1,490 @@ +/* + * 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. + */ +/* + * This Xinerama implementation comes from the SiS driver which has + * the following notice: + */ +/* + * SiS driver main code + * + * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1) Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2) Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3) The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Author: Thomas Winischhofer <thomas@winischhofer.net> + * - driver entirely rewritten since 2001, only basic structure taken from + * old code (except sis_dri.c, sis_shadow.c, sis_accel.c and parts of + * sis_dga.c; these were mostly taken over; sis_dri.c was changed for + * new versions of the DRI layer) + * + * This notice covers the entire driver code unless indicated otherwise. + * + * Formerly based on code which was + * Copyright (C) 1998, 1999 by Alan Hourihane, Wigan, England. + * Written by: + * Alan Hourihane <alanh@fairlite.demon.co.uk>, + * Mike Chapman <mike@paranoia.com>, + * Juanjo Santamarta <santamarta@ctv.es>, + * Mitani Hiroshi <hmitani@drl.mei.co.jp>, + * David Thomas <davtom@dream.org.uk>. + */ + +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */ +/* */ +/* NX-X11, NX protocol compression and NX extensions to this software */ +/* are copyright of NoMachine. Redistribution and use of the present */ +/* software is allowed according to terms specified in the file LICENSE */ +/* which comes in the source distribution. */ +/* */ +/* Check http://www.nomachine.com/licensing.html for applicability. */ +/* */ +/* NX and NoMachine are trademarks of Medialogic S.p.A. */ +/* */ +/* All rights reserved. */ +/* */ +/**************************************************************************/ + +#include "randrstr.h" +#include "swaprep.h" +#ifndef NXAGENT_SERVER +#include <X11/extensions/panoramiXproto.h> +#else +#include "panoramiXproto.h" +#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 + +static int ProcRRXineramaQueryVersion(ClientPtr client); +static int ProcRRXineramaGetState(ClientPtr client); +static int ProcRRXineramaGetScreenCount(ClientPtr client); +static int ProcRRXineramaGetScreenSize(ClientPtr client); +static int ProcRRXineramaIsActive(ClientPtr client); +static int ProcRRXineramaQueryScreens(ClientPtr client); +static int SProcRRXineramaDispatch(ClientPtr client); + +/* Proc */ + +int +ProcRRXineramaQueryVersion(ClientPtr client) +{ + xPanoramiXQueryVersionReply rep; + register int n; + + 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); + swaps(&rep.majorVersion, n); + swaps(&rep.minorVersion, n); + } + WriteToClient(client, sizeof(xPanoramiXQueryVersionReply), (char *)&rep); + return (client->noClientException); +} + +int +ProcRRXineramaGetState(ClientPtr client) +{ + REQUEST(xPanoramiXGetStateReq); + WindowPtr pWin; + xPanoramiXGetStateReply rep; + register int n, rc; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + Bool active = FALSE; + + REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); + #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) + { + /* XXX do we need more than this? */ + active = TRUE; + } + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.state = active; + rep.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; +} + +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; +} + +static Bool +RRXineramaScreenActive (ScreenPtr pScreen) +{ + return RRXineramaScreenCount (pScreen) > 0; +} + +int +ProcRRXineramaGetScreenCount(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenCountReq); + WindowPtr pWin; + xPanoramiXGetScreenCountReply rep; + register int n, rc; + + REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); + #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; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.ScreenCount = RRXineramaScreenCount (pWin->drawable.pScreen); + rep.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; +} + +int +ProcRRXineramaGetScreenSize(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenSizeReq); + WindowPtr pWin, pRoot; + ScreenPtr pScreen; + xPanoramiXGetScreenSizeReply rep; + register int n, rc; + + REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); + #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; + 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; + if(client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.width, n); + swapl(&rep.height, n); + swapl(&rep.window, n); + swapl(&rep.screen, n); + } + WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep); + return client->noClientException; +} + +int +ProcRRXineramaIsActive(ClientPtr client) +{ + xXineramaIsActiveReply rep; + + REQUEST_SIZE_MATCH(xXineramaIsActiveReq); + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.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; +} + +int +ProcRRXineramaQueryScreens(ClientPtr client) +{ + xXineramaQueryScreensReply rep; + ScreenPtr pScreen = screenInfo.screens[RR_XINERAMA_SCREEN]; + + REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); + + if (RRXineramaScreenActive (pScreen)) + { + rrScrPriv(pScreen); + if (pScrPriv->numCrtcs == 0 || pScrPriv->numOutputs == 0) + RRGetInfo (pScreen); + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.number = RRXineramaScreenCount (pScreen); + rep.length = rep.number * sz_XineramaScreenInfo >> 2; + 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); + } + } + } + + return client->noClientException; +} + +static int +ProcRRXineramaDispatch(ClientPtr client) +{ + REQUEST(xReq); + switch (stuff->data) { + case X_PanoramiXQueryVersion: + return ProcRRXineramaQueryVersion(client); + case X_PanoramiXGetState: + return ProcRRXineramaGetState(client); + case X_PanoramiXGetScreenCount: + return ProcRRXineramaGetScreenCount(client); + case X_PanoramiXGetScreenSize: + return ProcRRXineramaGetScreenSize(client); + case X_XineramaIsActive: + return ProcRRXineramaIsActive(client); + case X_XineramaQueryScreens: + return ProcRRXineramaQueryScreens(client); + } + return BadRequest; +} + +/* SProc */ + +static int +SProcRRXineramaQueryVersion (ClientPtr client) +{ + REQUEST(xPanoramiXQueryVersionReq); + register int n; + swaps(&stuff->length,n); + REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq); + return ProcRRXineramaQueryVersion(client); +} + +static int +SProcRRXineramaGetState(ClientPtr client) +{ + REQUEST(xPanoramiXGetStateReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); + swapl (&stuff->window, n); + return ProcRRXineramaGetState(client); +} + +static int +SProcRRXineramaGetScreenCount(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenCountReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); + swapl (&stuff->window, n); + return ProcRRXineramaGetScreenCount(client); +} + +static int +SProcRRXineramaGetScreenSize(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenSizeReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); + swapl (&stuff->window, n); + swapl (&stuff->screen, n); + return ProcRRXineramaGetScreenSize(client); +} + +static int +SProcRRXineramaIsActive(ClientPtr client) +{ + REQUEST(xXineramaIsActiveReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXineramaIsActiveReq); + return ProcRRXineramaIsActive(client); +} + +static int +SProcRRXineramaQueryScreens(ClientPtr client) +{ + REQUEST(xXineramaQueryScreensReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); + return ProcRRXineramaQueryScreens(client); +} + +int +SProcRRXineramaDispatch(ClientPtr client) +{ + REQUEST(xReq); + switch (stuff->data) { + case X_PanoramiXQueryVersion: + return SProcRRXineramaQueryVersion(client); + case X_PanoramiXGetState: + return SProcRRXineramaGetState(client); + case X_PanoramiXGetScreenCount: + return SProcRRXineramaGetScreenCount(client); + case X_PanoramiXGetScreenSize: + return SProcRRXineramaGetScreenSize(client); + case X_XineramaIsActive: + return SProcRRXineramaIsActive(client); + case X_XineramaQueryScreens: + return SProcRRXineramaQueryScreens(client); + } + return BadRequest; +} + +static void +RRXineramaResetProc(ExtensionEntry* extEntry) +{ +} + +void +RRXineramaExtensionInit(void) +{ +#ifdef PANORAMIX + if(!noPanoramiXExtension) + return; +#endif + + /* + * Xinerama isn't capable enough to have multiple protocol screens each + * with their own output geometry. So if there's more than one protocol + * screen, just don't even try. + */ + if (screenInfo.numScreens > 1) + return; + + (void) AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0, + ProcRRXineramaDispatch, + SProcRRXineramaDispatch, + RRXineramaResetProc, + StandardMinorOpcode); +} diff --git a/programs/Xserver/randr/rrxinerama.c.NX.original b/programs/Xserver/randr/rrxinerama.c.NX.original new file mode 100644 index 0000000..9f11279 --- /dev/null +++ b/programs/Xserver/randr/rrxinerama.c.NX.original @@ -0,0 +1,490 @@ +/* + * 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. + */ +/* + * This Xinerama implementation comes from the SiS driver which has + * the following notice: + */ +/* + * SiS driver main code + * + * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1) Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2) Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3) The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Author: Thomas Winischhofer <thomas@winischhofer.net> + * - driver entirely rewritten since 2001, only basic structure taken from + * old code (except sis_dri.c, sis_shadow.c, sis_accel.c and parts of + * sis_dga.c; these were mostly taken over; sis_dri.c was changed for + * new versions of the DRI layer) + * + * This notice covers the entire driver code unless indicated otherwise. + * + * Formerly based on code which was + * Copyright (C) 1998, 1999 by Alan Hourihane, Wigan, England. + * Written by: + * Alan Hourihane <alanh@fairlite.demon.co.uk>, + * Mike Chapman <mike@paranoia.com>, + * Juanjo Santamarta <santamarta@ctv.es>, + * Mitani Hiroshi <hmitani@drl.mei.co.jp>, + * David Thomas <davtom@dream.org.uk>. + */ + +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */ +/* */ +/* NX-X11, NX protocol compression and NX extensions to this software */ +/* are copyright of NoMachine. Redistribution and use of the present */ +/* software is allowed according to terms specified in the file LICENSE */ +/* which comes in the source distribution. */ +/* */ +/* Check http://www.nomachine.com/licensing.html for applicability. */ +/* */ +/* NX and NoMachine are trademarks of Medialogic S.p.A. */ +/* */ +/* All rights reserved. */ +/* */ +/**************************************************************************/ + +#include "randrstr.h" +#include "swaprep.h" +#ifndef NXAGENT_SERVER +#include <X11/extensions/panoramiXproto.h> +#else +#include "panoramiXproto.h" +#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 + +static int ProcRRXineramaQueryVersion(ClientPtr client); +static int ProcRRXineramaGetState(ClientPtr client); +static int ProcRRXineramaGetScreenCount(ClientPtr client); +static int ProcRRXineramaGetScreenSize(ClientPtr client); +static int ProcRRXineramaIsActive(ClientPtr client); +static int ProcRRXineramaQueryScreens(ClientPtr client); +static int SProcRRXineramaDispatch(ClientPtr client); + +/* Proc */ + +int +ProcRRXineramaQueryVersion(ClientPtr client) +{ + xPanoramiXQueryVersionReply rep; + register int n; + + 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); + swaps(&rep.majorVersion, n); + swaps(&rep.minorVersion, n); + } + WriteToClient(client, sizeof(xPanoramiXQueryVersionReply), (char *)&rep); + return (client->noClientException); +} + +int +ProcRRXineramaGetState(ClientPtr client) +{ + REQUEST(xPanoramiXGetStateReq); + WindowPtr pWin; + xPanoramiXGetStateReply rep; + register int n, rc; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + Bool active = FALSE; + + REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); + #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) + { + /* XXX do we need more than this? */ + active = TRUE; + } + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.state = active; + rep.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; +} + +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; +} + +static Bool +RRXineramaScreenActive (ScreenPtr pScreen) +{ + return RRXineramaScreenCount (pScreen) > 0; +} + +int +ProcRRXineramaGetScreenCount(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenCountReq); + WindowPtr pWin; + xPanoramiXGetScreenCountReply rep; + register int n, rc; + + REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); + #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; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.ScreenCount = RRXineramaScreenCount (pWin->drawable.pScreen); + rep.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; +} + +int +ProcRRXineramaGetScreenSize(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenSizeReq); + WindowPtr pWin, pRoot; + ScreenPtr pScreen; + xPanoramiXGetScreenSizeReply rep; + register int n, rc; + + REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); + #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; + 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; + if(client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.width, n); + swapl(&rep.height, n); + swapl(&rep.window, n); + swapl(&rep.screen, n); + } + WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep); + return client->noClientException; +} + +int +ProcRRXineramaIsActive(ClientPtr client) +{ + xXineramaIsActiveReply rep; + + REQUEST_SIZE_MATCH(xXineramaIsActiveReq); + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.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; +} + +int +ProcRRXineramaQueryScreens(ClientPtr client) +{ + xXineramaQueryScreensReply rep; + ScreenPtr pScreen = screenInfo.screens[RR_XINERAMA_SCREEN]; + + REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); + + if (RRXineramaScreenActive (pScreen)) + { + rrScrPriv(pScreen); + if (pScrPriv->numCrtcs == 0 || pScrPriv->numOutputs == 0) + RRGetInfo (pScreen); + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.number = RRXineramaScreenCount (pScreen); + rep.length = rep.number * sz_XineramaScreenInfo >> 2; + 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); + } + } + } + + return client->noClientException; +} + +static int +ProcRRXineramaDispatch(ClientPtr client) +{ + REQUEST(xReq); + switch (stuff->data) { + case X_PanoramiXQueryVersion: + return ProcRRXineramaQueryVersion(client); + case X_PanoramiXGetState: + return ProcRRXineramaGetState(client); + case X_PanoramiXGetScreenCount: + return ProcRRXineramaGetScreenCount(client); + case X_PanoramiXGetScreenSize: + return ProcRRXineramaGetScreenSize(client); + case X_XineramaIsActive: + return ProcRRXineramaIsActive(client); + case X_XineramaQueryScreens: + return ProcRRXineramaQueryScreens(client); + } + return BadRequest; +} + +/* SProc */ + +static int +SProcRRXineramaQueryVersion (ClientPtr client) +{ + REQUEST(xPanoramiXQueryVersionReq); + register int n; + swaps(&stuff->length,n); + REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq); + return ProcRRXineramaQueryVersion(client); +} + +static int +SProcRRXineramaGetState(ClientPtr client) +{ + REQUEST(xPanoramiXGetStateReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); + swapl (&stuff->window, n); + return ProcRRXineramaGetState(client); +} + +static int +SProcRRXineramaGetScreenCount(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenCountReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); + swapl (&stuff->window, n); + return ProcRRXineramaGetScreenCount(client); +} + +static int +SProcRRXineramaGetScreenSize(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenSizeReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); + swapl (&stuff->window, n); + swapl (&stuff->screen, n); + return ProcRRXineramaGetScreenSize(client); +} + +static int +SProcRRXineramaIsActive(ClientPtr client) +{ + REQUEST(xXineramaIsActiveReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXineramaIsActiveReq); + return ProcRRXineramaIsActive(client); +} + +static int +SProcRRXineramaQueryScreens(ClientPtr client) +{ + REQUEST(xXineramaQueryScreensReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); + return ProcRRXineramaQueryScreens(client); +} + +int +SProcRRXineramaDispatch(ClientPtr client) +{ + REQUEST(xReq); + switch (stuff->data) { + case X_PanoramiXQueryVersion: + return SProcRRXineramaQueryVersion(client); + case X_PanoramiXGetState: + return SProcRRXineramaGetState(client); + case X_PanoramiXGetScreenCount: + return SProcRRXineramaGetScreenCount(client); + case X_PanoramiXGetScreenSize: + return SProcRRXineramaGetScreenSize(client); + case X_XineramaIsActive: + return SProcRRXineramaIsActive(client); + case X_XineramaQueryScreens: + return SProcRRXineramaQueryScreens(client); + } + return BadRequest; +} + +static void +RRXineramaResetProc(ExtensionEntry* extEntry) +{ +} + +void +RRXineramaExtensionInit(void) +{ +#ifdef PANORAMIX + if(!noPanoramiXExtension) + return; +#endif + + /* + * Xinerama isn't capable enough to have multiple protocol screens each + * with their own output geometry. So if there's more than one protocol + * screen, just don't even try. + */ + if (screenInfo.numScreens > 1) + return; + + (void) AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0, + ProcRRXineramaDispatch, + SProcRRXineramaDispatch, + RRXineramaResetProc, + StandardMinorOpcode); +} diff --git a/programs/Xserver/randr/rrxinerama.c.X.original b/programs/Xserver/randr/rrxinerama.c.X.original new file mode 100644 index 0000000..e6acd5e --- /dev/null +++ b/programs/Xserver/randr/rrxinerama.c.X.original @@ -0,0 +1,454 @@ +/* + * 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. + */ +/* + * This Xinerama implementation comes from the SiS driver which has + * the following notice: + */ +/* + * SiS driver main code + * + * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1) Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2) Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3) The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Author: Thomas Winischhofer <thomas@winischhofer.net> + * - driver entirely rewritten since 2001, only basic structure taken from + * old code (except sis_dri.c, sis_shadow.c, sis_accel.c and parts of + * sis_dga.c; these were mostly taken over; sis_dri.c was changed for + * new versions of the DRI layer) + * + * This notice covers the entire driver code unless indicated otherwise. + * + * Formerly based on code which was + * Copyright (C) 1998, 1999 by Alan Hourihane, Wigan, England. + * Written by: + * Alan Hourihane <alanh@fairlite.demon.co.uk>, + * Mike Chapman <mike@paranoia.com>, + * Juanjo Santamarta <santamarta@ctv.es>, + * Mitani Hiroshi <hmitani@drl.mei.co.jp>, + * David Thomas <davtom@dream.org.uk>. + */ + +#include "randrstr.h" +#include "swaprep.h" +#include <X11/extensions/panoramiXproto.h> + +#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 + +static int ProcRRXineramaQueryVersion(ClientPtr client); +static int ProcRRXineramaGetState(ClientPtr client); +static int ProcRRXineramaGetScreenCount(ClientPtr client); +static int ProcRRXineramaGetScreenSize(ClientPtr client); +static int ProcRRXineramaIsActive(ClientPtr client); +static int ProcRRXineramaQueryScreens(ClientPtr client); +static int SProcRRXineramaDispatch(ClientPtr client); + +/* Proc */ + +int +ProcRRXineramaQueryVersion(ClientPtr client) +{ + xPanoramiXQueryVersionReply rep; + register int n; + + 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); + swaps(&rep.majorVersion, n); + swaps(&rep.minorVersion, n); + } + WriteToClient(client, sizeof(xPanoramiXQueryVersionReply), (char *)&rep); + return (client->noClientException); +} + +int +ProcRRXineramaGetState(ClientPtr client) +{ + REQUEST(xPanoramiXGetStateReq); + WindowPtr pWin; + xPanoramiXGetStateReply rep; + register int n, rc; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + Bool active = FALSE; + + REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); + if(rc != Success) + return rc; + + pScreen = pWin->drawable.pScreen; + pScrPriv = rrGetScrPriv(pScreen); + if (pScrPriv) + { + /* XXX do we need more than this? */ + active = TRUE; + } + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.state = active; + rep.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; +} + +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; +} + +static Bool +RRXineramaScreenActive (ScreenPtr pScreen) +{ + return RRXineramaScreenCount (pScreen) > 0; +} + +int +ProcRRXineramaGetScreenCount(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenCountReq); + WindowPtr pWin; + xPanoramiXGetScreenCountReply rep; + register int n, rc; + + REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); + 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; + if(client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.window, n); + } + WriteToClient(client, sizeof(xPanoramiXGetScreenCountReply), (char *)&rep); + return client->noClientException; +} + +int +ProcRRXineramaGetScreenSize(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenSizeReq); + WindowPtr pWin, pRoot; + ScreenPtr pScreen; + xPanoramiXGetScreenSizeReply rep; + register int n, rc; + + REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); + 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; + if(client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.width, n); + swapl(&rep.height, n); + swapl(&rep.window, n); + swapl(&rep.screen, n); + } + WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep); + return client->noClientException; +} + +int +ProcRRXineramaIsActive(ClientPtr client) +{ + xXineramaIsActiveReply rep; + + REQUEST_SIZE_MATCH(xXineramaIsActiveReq); + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.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; +} + +int +ProcRRXineramaQueryScreens(ClientPtr client) +{ + xXineramaQueryScreensReply rep; + ScreenPtr pScreen = screenInfo.screens[RR_XINERAMA_SCREEN]; + + REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); + + if (RRXineramaScreenActive (pScreen)) + { + rrScrPriv(pScreen); + if (pScrPriv->numCrtcs == 0 || pScrPriv->numOutputs == 0) + RRGetInfo (pScreen); + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.number = RRXineramaScreenCount (pScreen); + rep.length = rep.number * sz_XineramaScreenInfo >> 2; + 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); + } + } + } + + return client->noClientException; +} + +static int +ProcRRXineramaDispatch(ClientPtr client) +{ + REQUEST(xReq); + switch (stuff->data) { + case X_PanoramiXQueryVersion: + return ProcRRXineramaQueryVersion(client); + case X_PanoramiXGetState: + return ProcRRXineramaGetState(client); + case X_PanoramiXGetScreenCount: + return ProcRRXineramaGetScreenCount(client); + case X_PanoramiXGetScreenSize: + return ProcRRXineramaGetScreenSize(client); + case X_XineramaIsActive: + return ProcRRXineramaIsActive(client); + case X_XineramaQueryScreens: + return ProcRRXineramaQueryScreens(client); + } + return BadRequest; +} + +/* SProc */ + +static int +SProcRRXineramaQueryVersion (ClientPtr client) +{ + REQUEST(xPanoramiXQueryVersionReq); + register int n; + swaps(&stuff->length,n); + REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq); + return ProcRRXineramaQueryVersion(client); +} + +static int +SProcRRXineramaGetState(ClientPtr client) +{ + REQUEST(xPanoramiXGetStateReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); + swapl (&stuff->window, n); + return ProcRRXineramaGetState(client); +} + +static int +SProcRRXineramaGetScreenCount(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenCountReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); + swapl (&stuff->window, n); + return ProcRRXineramaGetScreenCount(client); +} + +static int +SProcRRXineramaGetScreenSize(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenSizeReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); + swapl (&stuff->window, n); + swapl (&stuff->screen, n); + return ProcRRXineramaGetScreenSize(client); +} + +static int +SProcRRXineramaIsActive(ClientPtr client) +{ + REQUEST(xXineramaIsActiveReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXineramaIsActiveReq); + return ProcRRXineramaIsActive(client); +} + +static int +SProcRRXineramaQueryScreens(ClientPtr client) +{ + REQUEST(xXineramaQueryScreensReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); + return ProcRRXineramaQueryScreens(client); +} + +int +SProcRRXineramaDispatch(ClientPtr client) +{ + REQUEST(xReq); + switch (stuff->data) { + case X_PanoramiXQueryVersion: + return SProcRRXineramaQueryVersion(client); + case X_PanoramiXGetState: + return SProcRRXineramaGetState(client); + case X_PanoramiXGetScreenCount: + return SProcRRXineramaGetScreenCount(client); + case X_PanoramiXGetScreenSize: + return SProcRRXineramaGetScreenSize(client); + case X_XineramaIsActive: + return SProcRRXineramaIsActive(client); + case X_XineramaQueryScreens: + return SProcRRXineramaQueryScreens(client); + } + return BadRequest; +} + +static void +RRXineramaResetProc(ExtensionEntry* extEntry) +{ +} + +void +RRXineramaExtensionInit(void) +{ +#ifdef PANORAMIX + if(!noPanoramiXExtension) + return; +#endif + + /* + * Xinerama isn't capable enough to have multiple protocol screens each + * with their own output geometry. So if there's more than one protocol + * screen, just don't even try. + */ + if (screenInfo.numScreens > 1) + return; + + (void) AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0, + ProcRRXineramaDispatch, + SProcRRXineramaDispatch, + RRXineramaResetProc, + StandardMinorOpcode); +} hooks/post-receive -- x2goagent.git (X2go (NX-like) Agent) This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "x2goagent.git" (X2go (NX-like) Agent).